supabase / supabase-flutter

Flutter integration for Supabase. This package makes it simple for developers to build secure and scalable products.
https://supabase.com/
MIT License
662 stars 155 forks source link

User phone is not updating #953

Closed iosephmagno closed 1 week ago

iosephmagno commented 1 week ago

Describe the bug auth.updateUser should allow us to update user phone, but it doesnt work for some reason.

To Reproduce

await auth.updateUser(UserAttributes(phone: phone));
final response = await auth.updateUser(UserAttributes(phone: phone));
print( ‘DEBUG: phone $phone' );
print(‘DEBUG: Update Phone Number response user ${response.user}');

It can be noticed that response.user.phone gets not updated.

Expected behavior User phone should be updated with the new value.

Version (please complete the following information):

├── supabase_flutter 2.5.6
│   ├── supabase 2.2.2
│   │   ├── functions_client 2.2.0
│   │   ├── gotrue 2.8.1
│   │   ├── postgrest 2.1.2
│   │   ├── realtime_client 2.1.0
│   │   ├── storage_client 2.0.2
dshukertjr commented 1 week ago

The phone number will actually not be updated instantly. Instead, an OTP is sent to the user, and upon confirming the OTP, the phone number is updated on the auth.users table.

iosephmagno commented 1 week ago

Hi Tyler, we didn't notice that an OTP was sent. Will test it right now. However, with this flows that method should return a bool, not void. Otherwise how can we take action in result of the phone's change, just try/catch? Example flow: 1) user changes the phone number 2) auth.updateUser(UserAttributes(phone: phone)) return true and we can change user phone inside User table (not Auth table). Thx

dshukertjr commented 1 week ago

One thing that you could do is to setup a trigger on the auth.users table to update the phone number of your public.users table. This way, the phone number is always in sync with the auth.users table.

iosephmagno commented 1 week ago

Yes but the issue is also updating the UI after the change. Original UI shows the initial number, and after the method is completed successfully, the UI should be updated with new number.

We are not receiving an OTP, this is the error: Error updating 65819238034: AuthRetryableFetchError

iosephmagno commented 1 week ago

As for the trigger, we use them, but sometimes they fail. What if that trigger is never fired or an issue occurs after the trigger when updating the Users table. That would cause data inconsistency between client and server and we would not be aware of it.

dshukertjr commented 1 week ago

Postgres triggers always fire, and if an error is thrown, the entire operation is rolled back. It is the safest option for data consistency. https://www.postgresql.org/docs/current/sql-createtrigger.html

iosephmagno commented 1 week ago

Ok then we will adjust our UI accordingly. But method doesn't work. We don't receive OTP code and it doesnt throw error. No idea if number was changed inside Auth table, coz we cannot filter it by userId (which would be a welcome feature).

iosephmagno commented 1 week ago

Postgres triggers always fire, and if an error is thrown, the entire operation is rolled back. It is the safest option for data consistency. https://www.postgresql.org/docs/current/sql-createtrigger.html

Idk, roll back might left client in an inconsistent data state. The best thing for us would be if we could simply change the number from Auth ourselves and send otp code to user ouerselves (I mean without supabse, we already do that in some cases). Then if Auth table is updated, we will update Users table. This is 100% bug-free. Flow would be: 1) user asks to change number and fill in new number 2) we send to user the otp code 3) user fills in code and if it is success we: 3.1) change number in Auth table and if it is success we 3.2) change number in public.users tables. In all steps we can update UI state properly and manage exception easily. Having Supabase in the middle here is more an hassle than an help.

Note: Sending otp code via Twilio is super easy, and there are dart plugins as well twilio_phone_verify or twilio_flutter

iosephmagno commented 1 week ago

Can we change this

 Future<UserResponse> updateUser(
    UserAttributes attributes, {
    String? emailRedirectTo,
  }) 

to this:

 Future<UserResponse> updateUser(
    UserAttributes attributes, {
    String? emailRedirectTo,
    String? isOtpCodeVerified = false,
  }) 

If isOtpCodeVerified: true, that means that we already sent to user an otp code and verified it, so that updateUser() will be performed directly without sending otp code. That would simplify our life by a lot and also would allow us to code a more robust flow. The users who instead want supabase to send otp code, will keep using the method as it is now.

delfme commented 1 week ago

@dshukertjr can we meantime reopen this? We have tried with different numbers but otp code is never sent.

delfme commented 1 week ago

it is not easy to debug but from what discovered so far. Lets say user has two numbers A and B.

Given the situation, we cannot debug issue, coz supabase server is involved and is out of our control.