S
Supabase8mo ago
JC

Token has expired or is invalid

Hello! I launched a new Flutter app today and I have hundreds of users who are trying to sign up using verifyOtp, but they keep getting the error: "token has expired or is invalid". The weird thing is that I can't reproduce the error. Everything works great for me, and there are also several other users where it works fine. So I'm at a loss for what to try next. Here is the code I'm using to send a code to the user, who is signing up for the first time: final data = await Supabase.instance.client.auth.verifyOTP( email: widget.profileData['email'], token: _otpController.text, type: OtpType.email, ); Like I said, this works fine for me every time I use it in the simulator and on the production app. I've even deleted my user record in the auth.users table to start fresh, but the verification works fine for me and I get right in. Any help would be appreciated!
4 Replies
garyaustin
garyaustin8mo ago
Are you sending a link with the code or just a code? If you send a link it could be getting scanned by an email provider which will use the onetime token up.
JC
JCOP8mo ago
I’m only sending a code.
garyaustin
garyaustin8mo ago
You should look in the Gateway API and Auth logs for the error case. Then look to see if there is another call from the same user before it that works. Should be /verify end point. Something is likely causing the endpoint to run twice. Also can be extra space at beginning or end of string, but that would likely be a more occasional thing. Are the cases always the same users?
JC
JCOP8mo ago
Well, it turns out it was a race condition with a user record not getting properly inserted into my public.users table after the token was successfully verified. The expired token errors were just from users trying multiple times to verify their token after not successfully getting logged in from a token validation actually working. So I resolved the issue by adding a trigger to the auth.users table so that I immediately get a record inserted into my public.users table, and then I also added a 1 second delay after the validation response finishes just in case. Thanks for the help @garyaustin!

Did you find this page helpful?