firebase-android-sdk icon indicating copy to clipboard operation
firebase-android-sdk copied to clipboard

FirebaseAuth.getInstance().getCurrentUser().getUid() returning numbers in place of actual user id

Open sipersso opened this issue 3 years ago • 36 comments

[READ] Step 1: Are you in the right place?

Issues filed here should be about bugs in the code in this repository. If you have a general question, need help debugging, or fall into some other category use one of these other channels:

  • For general technical questions, post a question on StackOverflow with the firebase tag.
  • For general Firebase discussion, use the firebase-talk google group.
  • For help troubleshooting your application that does not fall under one of the above categories, reach out to the personalized Firebase support channel.

[REQUIRED] Step 2: Describe your environment

  • Android Studio version: 4.1.2
  • Firebase Component: Auth
  • Component version: 19.3.0 (Firebase UI 6.3.0)

[REQUIRED] Step 3: Describe the problem

I am copying the description of this issue #1927 since I am experiencing the exact same issue.

Here is the description of #1927 "Using FirebaseAuth.getInstance().getCurrentUser().getUid() to get the user id of the user. This method is returning numbers instead of the actual user id in some case. Also, we find the users token is still valid but the user id returning from the SDK is of number example: 101528418014522522531"

I have had this reported by customers a happen a few times, and it has caused authentication to silently break for them, which is unnacceptable.

Steps to reproduce:

Sorry, not able to reproduce the issue and was got from Crashlytics for some users

Relevant Code:

 FirebaseAuth.getInstance().getCurrentUser().getUid()

sipersso avatar Feb 11 '21 08:02 sipersso

I found a few problems with this issue:

  • I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.
  • This issue does not seem to follow the issue template. Make sure you provide all the required information.

google-oss-bot avatar Feb 11 '21 08:02 google-oss-bot

I didn't want to create a new issue for this, but since #1927 is closed, I am not allowed to make comments or open that issue. This is the same issue as that one.

Updated the issue so I think it follows the template now.

sipersso avatar Feb 11 '21 10:02 sipersso

I am guessing the user has corrupted info in the KeyChain. Apparently the issue persists even if the app is uninstalled.

sipersso avatar Feb 12 '21 17:02 sipersso

This happened again today. Since the problem persists on reinstall it is really hard to fix this for the end user and the app can't be used at all.

sipersso avatar Jun 09 '21 10:06 sipersso

Hey there sipersso, sorry that this issue appears to have fallen between the cracks. Is a user is having a persistent issue, then can always clear the application data or uninstall/reinstall the application to get the current session to clear out. If that doesn't work, check what the user looks like on export as compared with a user not seeing the issue, please :)

As for why this happens, the version of Auth you are using was published over a year ago, so it's difficult for me to track down why that might be happening. Does this still happen on the latest version of the SDK?

malcolmdeck avatar Jun 14 '21 19:06 malcolmdeck

1: The current version I use is 20.0.2 and firebase-bom: 26.5.0. I'll be sure to update it, but I am not using a version that is a year old. 2: Deleting and reinstalling the app is not a great for two reasons. First, the user will loose any data that hasn't been synced since the error happened. Second, deleting and reinstalling doesn't solve the issue since it is caused by data persistent in the keychain.

What the user needs to do is to 1: Reach out to support so they can manually send me their data and I can recover it for them 2: Go to the settings app and clear app data. This will remove all content and clear the keychain for the app.

For the user, this is an awful experience. The weird things it that Firebase Auth is not throwing any errors. I would expect the user to be signed out if the keychain has been corrupted, or at least to get an error somewhere. If the user would have been signed out right away, the impact would be minimal as it would be forced to sign in again. Now, they can go for a long time without really noticing that their login doesn't work, which is awful.

What do you mean by "check what the user looks like on export"?

sipersso avatar Jun 15 '21 06:06 sipersso

This is still an issue. Currently using com.google.firebase:firebase-bom:29.0.0, that affects a small number of users.

sipersso avatar Nov 12 '21 21:11 sipersso

After being in touch with Firebase support (case 10155473) I actually has some more insight on this one. The numbers that getUID returns are not random!

I do see some permission errors in crashlytics related to this error. When auth returns the wrong UID this will cause permission errors down the line

Here is the interesting part. I did an firebase auth:export and searched for the invalid ids. To my surprise I actually found them! It turns out that user.getUid() can sometimes return other identifiers than the UID. In this case id I saw with all numbers was actually the google sign in uid. I also found cases where firebaseUser.getUid() would return an email adress.

Could this be a database migration gone wrong? Do you access these properties by column index?

sipersso avatar Dec 09 '21 07:12 sipersso

Good find sipersso - that actually helps a lot. I've filed b/210006469 to track this internally, and hopefully someone on our backend team can help shed some light on this for us :)

malcolmdeck avatar Dec 09 '21 19:12 malcolmdeck

@malcolmdeck were you able to get any info on this? I still have users affected by this error. It is very rare, but it does happen occasionally and since I don't get any errors, just an invalid ID, error handling is super tricky.

sipersso avatar Jan 28 '22 07:01 sipersso

I am also affected by this issue. I can confirm that the numbers are not random. If the user id is invalid (not 28 char alphanumeric), it will be one of the provider UIDs instead. I see a numeric UID when the provider is google, and an email UID when the provider is firebase password. I haven't been able to reproduce it myself so far.

I see it most frequently after the user brings the app back into focus and the FirebaseAuth.StateChanged event is triggered - the UID will be correct when the app goes out of focus, and FirebaseUser.UserId will be wrong after StateChanged triggers once the app comes back into focus.

Unity Firebase SDK 8.8.0

com.google.firebase.firebase-abt-21.0.1 com.google.firebase.firebase-analytics-20.0.2 com.google.firebase.firebase-analytics-unity-8.8.0 com.google.firebase.firebase-annotations-16.0.0 com.google.firebase.firebase-app-unity-8.8.0 com.google.firebase.firebase-appcheck-interop-16.0.0-beta02 com.google.firebase.firebase-auth-21.0.3 com.google.firebase.firebase-auth-interop-20.0.0 com.google.firebase.firebase-auth-unity-8.8.0 com.google.firebase.firebase-common-20.1.0 com.google.firebase.firebase-components-17.0.0 com.google.firebase.firebase-config-21.0.2 com.google.firebase.firebase-config-unity-8.8.0 com.google.firebase.firebase-crashlytics-18.2.9 com.google.firebase.firebase-crashlytics-ndk-18.2.9 com.google.firebase.firebase-crashlytics-unity-8.8.0 com.google.firebase.firebase-datatrasnport-18.1.1 com.google.firebase.firebase-encoders-17.0.0 com.google.firebase.firebase-encoders-json-18.0.0 com.google.firebase.firebase-encoders-proto-16.0.0 com.google.firebase.firebase-functions-20.0.2 com.google.firebase.firebase-functions-unity-8.8.0 com.google.firebase.firebase-iid-21.1.0 com.google.firebase.firebase-iid-interop-17.1.0 com.google.firebase.firebase-installations-17.0.1 com.google.firebase.firebase-installations-interop-17.0.1 com.google.firebase.firebase-measurement-connector-19.0.0 com.google.firebase.firebase-messaging-23.0.2 com.google.firebase.firebase-messaging-unity-8.8.0

allenmrazek avatar Apr 08 '22 18:04 allenmrazek

Thanks for the more detailed information - the in-focus out-of-focus thing is interesting, it gives me another place to look at where this might be an issue (in storage rather than over-the-wire).

malcolmdeck avatar Apr 08 '22 18:04 malcolmdeck

I reported this issue to Firebase support on Nov 22, 2019. But the issue was not reproducible. We had a lot of discussions.

Here is the case ref:

Case 00023876: Firebase Auth issue [ ref:_00D1Ux0Jq._5001UO6FzC:ref ]

I have added the following workaround on Jul 29, 2020, (I shared the workaround to the Firebase support) to resolve the issue: Screen Shot 2020-07-29 at 11 31 12 AM

So basically, I'm checking if the uid is invalid then just log out the user. Because in my case it is always the email address of the user.

deepak786 avatar Apr 14 '22 18:04 deepak786

This is issue has been out now for over 3 years and no explanation or fix whatsoever. We're facing it again in 2022. Not many users, but again FirebaseAuth.getInstance().getCurrentUser().getUid() returns e-mail adresses instead of an id.

The bad thing is, that because of firebase database moaning to the client if the uid (which is a mail) is used for fetching data, we end up having email adresses now in crashlytics logs. Which is not good.

If this helps: When I lookup the e-mail in firebase authentication, I see that the user does indeed have a uid.

SteveBurkert avatar May 11 '22 15:05 SteveBurkert

I can confirm that this is still happening on Android firebase-bom:30.0.0. I have one single user where FirebaseAuth.getInstance().getCurrentUser().getUid() is returning their email, causing the app to be unusable.

maclne avatar Jun 09 '22 19:06 maclne

@malcolmdeck Any updates on this issue? I'd say it is pretty critical and it's been open for quite some time now.

sipersso avatar Jun 10 '22 12:06 sipersso

For now, my workaround has been to grab the UID from the JWT instead if the UID looks like it's invalid so I can avoid forcibly logging the user out. This issue seems specific to Android since I don't see any cases happening on iOS (although our user count there is much lower so I can't be certain).

allenmrazek avatar Jun 10 '22 18:06 allenmrazek

@allenmrazek Thank you for that. I can't believe it is needed, but that does sound like a good way to verify that FirebaseAuth is incorrect. Regarding iOS, I have more users on iOS than on Android and have never seen the same error on iOS. It does indeed sound as if this is an Android-only problem.

sipersso avatar Jun 11 '22 09:06 sipersso

I went through Firebase Support, but they can't or won't escalate the issue to the engineering team unless I can reproduce the issue using our quickstart for Android: https://github.com/firebase/quickstart-android/tree/master/auth.

This may be a dumb question, but how do you grab the UID from JWT? Would it still be the same UID that you would get from getCurrentUser().getUid() ?

maclne avatar Jun 22 '22 14:06 maclne

@maclne Yes, same UID (the correct UID, not the wrong one). I'm using Unity with firebase so this is C#, but the steps are:

  1. Get user token (TokenAsync)
  2. Convert payload section into json
  3. Read user_id from json

Here's a C# snippet with some error handling stripped out:

var pieces = idToken.Split('.'); // header, payload, signature
var payloadBase64 = pieces[1];

switch (payloadBase64.Length % 4)
{
    case 1: payloadBase64 += "==="; break;
    case 2: payloadBase64 += "=="; break;
    case 3: payloadBase64 += "="; break;
}

var payloadSection = Encoding.UTF8.GetString(Convert.FromBase64String(payloadBase64));
var json = SimpleJSON.JSON.Parse(payloadSection);
var payloadUserId = json["user_id"].Value; // always correct UID

allenmrazek avatar Jun 22 '22 17:06 allenmrazek

This is a great workaround. Thanks @allenmrazek

Here's the java equivalent for anyone running into the same issue:

if(this.mAuth.getCurrentUser().getUid().contains(".")) { this.mAuth.getCurrentUser().getIdToken(true).addOnSuccessListener(new OnSuccessListener<GetTokenResult>() { @Override public void onSuccess(GetTokenResult result) { String idToken = result.getToken(); String[] pieces = idToken.split("\."); // header, payload, signature String payloadBase64 = pieces[1];

                switch (payloadBase64.length() % 4) {
                    case 1:
                        payloadBase64 += "===";
                        break;
                    case 2:
                        payloadBase64 += "==";
                        break;
                    case 3:
                        payloadBase64 += "=";
                        break;
                }

                try {
                    String payloadSection = new String(Base64.decode(payloadBase64, Base64.DEFAULT), "UTF-8");
                    JSONObject json = new JSONObject(payloadSection);
                    tokenUID = json.getString("user_id"); // always correct UID
                } catch (JSONException e) {
                    e.printStackTrace();
                } catch (UnsupportedEncodingException ex) {
                    ex.printStackTrace();
                }
            }
        });
    }

**Note that @amondnet post below works as well and is much simpler.

maclne avatar Jun 22 '22 21:06 maclne

@maclne https://firebase.google.com/docs/reference/android/com/google/firebase/auth/GetTokenResult#public-mapstring,-object-getclaims

Returns the entire payload claims of the ID token including the standard reserved claims as well as the custom claims (set by developer via Admin SDK). Developers should verify the ID token and parse claims from its payload on the backend and never trust this value on the client. Returns an empty map if no claims are present.

Map<String, Object> claims = result.getClaims();
String uid = claims.get("sub"); // or claims.get("user_id")

amondnet avatar Jun 23 '22 09:06 amondnet

Any updates from the Firebase Team @malcolmdeck?

sipersso avatar Aug 07 '22 07:08 sipersso

It occurred to me now while I was testing my android mobile application on an emulator. Actually it just happened once. After trying to wipe out the emulator’s data and reinstalling the application, it worked normally and returned the uid.

shehabadel avatar Jan 02 '23 04:01 shehabadel

Hi folks, thanks for your patience with this issue! We are still investigating this and might have found a codepath where uid gets populated with ProviderInfo federated Id. It doesn't appear to be triggered in any valid scenario from what I can tell, but will keep this thread posted.

Can someone confirm if this happens with bom - 31.1.1?

prameshj avatar Jan 09 '23 22:01 prameshj

Hi @prameshj! I use 31.1.1 in production and I am still having issues with this. I have tracking on it in crashlytics and it is definitely happening

sipersso avatar Jan 24 '23 08:01 sipersso

@prameshj if it helps, it looks like this affected around 3% of my active users the past 7 days.

sipersso avatar Jan 24 '23 08:01 sipersso

Thanks for the additional info.. We are still working on a repro here and some ideas to recover from this state. Will keep this thread posted. Unfortunately, we are unable to share a concrete timeline, but it is on our radar.

prameshj avatar Jan 30 '23 20:01 prameshj

This is still an issue in BOM 31.2.2, which is leaking emails into Crashlytics and breaking Realtime Database queries. Any updates on progress here? I have dozens of users with this issue

If this info is useful, I've found this has gotten significantly worse when updating Firebase BOM from 29.3.1 to 31.2.0

mihinton avatar Mar 01 '23 19:03 mihinton

Thanks for the additional info. In case anyone is able to repro this in an emulator or happens to have the contents of adb logcat while they catch this issue happening, can you check if you see this logged:

Provider user info list size larger than max size

It is possible that some truncation is happening in some rare cases, but it is still not clear how we can end up here. we can try to fix this logic, but it is unclear if it will solve the issue. But the data on the logs will be helpful. Thanks!

prameshj avatar Mar 16 '23 23:03 prameshj