supabase-flutter
supabase-flutter copied to clipboard
PostgrestException(message: JWT expired, code: PGRST301, details: Unauthorized, hint: null)
I have a Flutter app with Supabase backend. when I want to read data from tables for the first 3 times calling the database it's all good working but after 3 times I am facing this error :
PostgrestException(message: JWT expired, code: PGRST301, details: Unauthorized, hint: null) the way I implement reading data is
Future<List<BrandModel>> getBrands() async {
List<BrandModel> data = [];
try {
var response = await supabase.from('brand').select();
data = (response as List).map((e) => BrandModel.fromJson(e)).toList();
} catch (e) {
print(e);
}
return data;
}
the main function is :
Future<void> main() async {
//? widget bindings
WidgetsFlutterBinding.ensureInitialized();
//? initializing supa
await Supabase.initialize(
url: AppConsts.supaBaseURL, anonKey: AppConsts.anonKey);
}
@dshukertjr the RLS policy of the table is also off and I have No Idea How to figure this out. can you suggest a solution for this?
@EddyHezarian How exactly are you calling the getBrands () function? Do you call it on a button press?
@dshukertjr its a future builder in screen :
FutureBuilder(
future: brandsApiProvider.getBrands(),
builder: (context, AsyncSnapshot<List<BrandModel>> snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
var currentDataIndex = snapshot.data![index];
return BrandCard(currentDataIndex: currentDataIndex);
});
} else {
return Container();
}
}),
You mentioned
after 3 times
, but with a FutureBuilder, how do you call it three times?
no when i mentioned 3 times i mean after implemented this screen , after each restarts this getBrands() got called and after third Restart App getBrands() throw this error : PostgrestException(message: JWT expired, code: PGRST301, details: Unauthorized, hint: null)
i changed the getBrands() like this :
Future<List<BrandModel>> getBrands() async {
List<BrandModel> data = [];
try {
var response = await supabase.from('brand').select();
data = (response as List).map((e) => BrandModel.fromJson(e)).toList();
} catch (e) {
if (e is PostgrestException && e.code == 'PGRST301') {
try {
await supabase.auth.refreshSession(); // Attempt to refresh the session
var response = await supabase.from('brand').select();
data = (response as List).map((e) => BrandModel.fromJson(e)).toList();
} catch (e) {
print(e)
}
}
}
return data;
}
it works but is it an efficient way to implement this?
@EddyHezarian Hmm, interesting. You shouldn't have to refresh the session manually like that. I wonder what is causing the token to expire.
Roughly how long does it take from calling getBrands() the first time to calling getBrands() the third time where it fails? Also, have you changed your Access token (JWT) expiry time from your Supabase dashboard? If so, what is it set to?
BTW, could you format your code block you share? It helps us read the code easier.
It may be the case that the function is being called too many times and the server is denying the request after a few times. Can you try the following snippet:
// in a StatefulWidget
late final brandsFuture = brandsApiProvider.getBrands();
FutureBuilder(
future: brandsFuture,
builder: (context, AsyncSnapshot<List<BrandModel>> snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
var currentDataIndex = snapshot.data![index];
return BrandCard(currentDataIndex: currentDataIndex);
});
} else {
return Container();
}
}),
This should call getBrands only when the widget is first built, not every time the build function is called. See the FutureBuilder documentation for more info.
What was the working solution @EddyHezarian ? I have the same issue and it is not going away when refreshing the session (next request is still throwing a PGRST301 error), even though the access key is properly refreshed.
@flogy Could you provide a sample code that is causing the error?
What was the working solution @EddyHezarian ? I have the same issue and it is not going away when refreshing the session (next request is still throwing a PGRST301 error), even though the access key is properly refreshed.
Same issue
What was the working solution @EddyHezarian ? I have the same issue and it is not going away when refreshing the session (next request is still throwing a PGRST301 error), even though the access key is properly refreshed.
After refreshing session its all good for me. Provide your code to better understand your issue.
We have shipped an update that will hopefully make things better with this issue. If you could try out v2.5.0 of supabase_flutter and see if things are better, that would be great.