Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PostgrestException(message: JWT expired, code: PGRST301, details: Unauthorized, hint: null) #788

Open
EddyHezarian opened this issue Jan 5, 2024 · 13 comments
Labels
bug Something isn't working postgrest This issue or pull request is related to postgrest

Comments

@EddyHezarian
Copy link

EddyHezarian commented Jan 5, 2024

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);
}
@EddyHezarian EddyHezarian added the bug Something isn't working label Jan 5, 2024
@dshukertjr dshukertjr added the postgrest This issue or pull request is related to postgrest label Jan 5, 2024
@EddyHezarian
Copy link
Author

@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?

@dshukertjr
Copy link
Member

@EddyHezarian How exactly are you calling the getBrands () function? Do you call it on a button press?

@EddyHezarian
Copy link
Author

EddyHezarian commented Jan 5, 2024

@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();
  }
}),

@dshukertjr
Copy link
Member

You mentioned

after 3 times

, but with a FutureBuilder, how do you call it three times?

@EddyHezarian
Copy link
Author

EddyHezarian commented Jan 5, 2024

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;
  }

@EddyHezarian
Copy link
Author

it works but is it an efficient way to implement this?

@dshukertjr
Copy link
Member

@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.

@bdlukaa
Copy link
Collaborator

bdlukaa commented Jan 7, 2024

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.

@flogy
Copy link

flogy commented Jan 25, 2024

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.

@dshukertjr
Copy link
Member

@flogy
Could you provide a sample code that is causing the error?

@dshukertjr dshukertjr reopened this Jan 26, 2024
@elliottetzkorn
Copy link
Contributor

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

@EddyHezarian
Copy link
Author

EddyHezarian commented Feb 22, 2024

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.

@dshukertjr
Copy link
Member

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working postgrest This issue or pull request is related to postgrest
Projects
None yet
Development

No branches or pull requests

5 participants