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

Bug: Auth.auth().currentUser Returns Nil on Some Devices Despite Available User Data.

Open jesus-mg-ios opened this issue 1 year ago • 51 comments

Description

The Auth.auth().currentUser property consistently returns nil on specific devices, even though a logged-in user is expected. In contrast, the getStoredUser(forAccessGroup:) method intermittently returns a user object, suggesting that the user data is accessible. The behavior remains consistent across device lifecycles, where the method either returns a user object or does not, without variation. The whole extension works on a concurrent environment.

Also functions are working authenticated despite Auth.auth().currentUser is nil. State listener does not change the rules, I mean, it does not change Auth.auth().currentUser, and also does not return other than nil on those cases Auth.auth().currentUser is nil.

Reproducing the issue


I'm not sure, but maybe it more reproducible when updates happens. Because what I saw in some cases is:

Auth.auth().currentUser is nil and getStoredUser(forAccessGroup:) is also nil until the user enters on the app, then getStoredUser(forAccessGroup:) returns a value in the extension.

Even sometimes both Auth.auth().currentUser getStoredUser(forAccessGroup:) are nil until the extension restart.

Could be any kind of deadlock trying to get the keychain element?

Firebase SDK Version

10.25

Xcode Version

15.2

Installation Method

Swift Package Manager

Firebase Product(s)

Authentication

Targeted Platforms

iOS, macCatalyst

Relevant Log Output

No response

If using Swift Package Manager, the project's Package.resolved

Expand Package.resolved snippet

Replace this line with the contents of your Package.resolved.

If using CocoaPods, the project's Podfile.lock

Expand Podfile.lock snippet

Replace this line with the contents of your Podfile.lock!

jesus-mg-ios avatar Jul 04 '24 07:07 jesus-mg-ios

@rizafran any update on this? The bug has a high repro on end devices.

jesus-mg-ios avatar Jul 09 '24 06:07 jesus-mg-ios

Thanks for reporting, @jesus-mg-ios. In order to investigate and replicate the issue, could you provide the following info:

  • Model and OS version of the affected devices
  • Sign in method you're using
  • Sample app that reproduces the issue

rizafran avatar Jul 09 '24 13:07 rizafran

Several ones...

  • XR, 14 Pro, 14 Pro Max, SE 3rd, 15 plus ...
  • Signing Method -> Apple Sign In
  • Right now I cannot provide you a sample. Please double check the issue related to this in which there's a crash to give you a hint about what can be happening.

jesus-mg-ios avatar Jul 09 '24 13:07 jesus-mg-ios

See this stackoverflow question and answer - https://stackoverflow.com/q/69201789/556617

paulb777 avatar Jul 09 '24 13:07 paulb777

I've already implemented a state listener @paulb777, but it didn't resolve the issue. The state listener initially triggers with a nil value, even though the data is available in the keychain, and it never triggers again with the correct user value.

jesus-mg-ios avatar Jul 09 '24 14:07 jesus-mg-ios

Does 11.0.0 (released today) make any difference?

paulb777 avatar Jul 31 '24 00:07 paulb777

Hey @jesus-mg-ios. We need more information to resolve this issue but there hasn't been an update in 5 weekdays. I'm marking the issue as stale and if there are no new updates in the next 5 days I will close it automatically.

If you have more information that will help us get to the bottom of this, just add a comment!

google-oss-bot avatar Aug 06 '24 01:08 google-oss-bot

I have the same issue on 11.0.0 .. each time i reset the app auth is nil! resetting entitlement did not help.

Downgrading to FirebaseCore 10.29.0 (was 11.0.0) solved the issue....

Removing FirebaseAppCheckInterop Removing FirebaseAuthInterop Removing FirebaseCoreExtension Removing FirebaseSharedSwift Removing RecaptchaInterop

not sure if those files have anything to do with it? those are removed after downgrade from 11

yarodevuci avatar Aug 07 '24 22:08 yarodevuci

@jesus-mg-ios have you figured it out ?

yarodevuci avatar Aug 07 '24 22:08 yarodevuci

@rizafran happens on any phones and simulator for me running iOS 17, can't test other OSs

Auth.auth().signIn(withEmail: email, password: xxx completion: { result, error in

Auth.auth().currentUser returns nil after app restart ..

yarodevuci avatar Aug 07 '24 22:08 yarodevuci

Hi @yarodevuci, I tried to reproduce the issue using v11.0.0 on iOS 17 simulator, but my currentUser is returning a value every time I restart the app. Is it possible for you to provide a sample app that reproduces the issue?

rizafran avatar Aug 12 '24 19:08 rizafran

Hi @yarodevuci, I tried to reproduce the issue using v11.0.0 on iOS 17 simulator, but my currentUser is returning a value every time I restart the app. Is it possible for you to provide a sample app that reproduces the issue?

I can draft maybe a sample app yes, do you know if between 10 and 11 version a new json config file needs to be updated?

Some people mentioned the updating their entitlements file helped too, so I am not sure if from brand new project issue does not exist, compared to older project

yarodevuci avatar Aug 12 '24 22:08 yarodevuci

@yarodevuci, may I know which json config file you're referring to?

rizafran avatar Aug 13 '24 19:08 rizafran

@yarodevuci, may I know which json config file you're referring to?

GoogleService-Info.plist

yarodevuci avatar Aug 14 '24 00:08 yarodevuci

Hi @yarodevuci, there's no need to update in your GoogleService-Info.plist file if you're updating to v11.0.

rizafran avatar Aug 20 '24 18:08 rizafran

@rizafran here is my update

I use to check in AppDelegate Auth.auth().currentUser != nil ... but now Auth.auth().currentUser is nil each time ..

I tried

Auth.auth().addStateDidChangeListener { auth, user in
         //Auth.auth().currentUser  is not nil here anymore
}

So I can't no longer use direct Auth.auth().currentUser in AppDelegate?

yarodevuci avatar Aug 26 '24 02:08 yarodevuci

I also faced this bug, Auth.auth().currentUser doesn't return logged in user in AppDelegate in Firebase 11.1.0.

In my apps, user is signed in anonymously when Auth.auth().currentUser == nil so now it's always logged in as anonymous.

    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        FirebaseApp.configure()
        
        if Auth.auth().currentUser == nil {
            Auth.auth().signInAnonymously { _, error in
                if let error = error {
                    print(error)
                }
            }
        }
        
        return true
    }

So I decided to switch back to Firebase 10.29.0.

minhnguyen-iosdev avatar Aug 28 '24 11:08 minhnguyen-iosdev

@rizafran can you let us know if this an actual bug or updated implementation usage is now required?

yarodevuci avatar Aug 28 '24 22:08 yarodevuci

Thanks for sharing more info, @yarodevuci. I was able to reproduce the same behavior and I've raised this to the engineer for investigation.

rizafran avatar Aug 29 '24 10:08 rizafran

+1 for this, I believe that our users are encountering an issue related to this bug in the wild.

dfmuir avatar Aug 31 '24 12:08 dfmuir

I've reproduced.

It's always been true that there is a race condition initializing currentUser.

However, it looks to be much more prevalent to be slower to initialize in Firebase 11.

After anonymous login, currentUser is initialized after the configure call in Firebase 10, but not 11.

I've isolated to the keychain read - OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)returningQuery, (CFTypeRef *)&result);

In Firebase 11, the worker thread gives up control, but Firebase 10 does not.

I even converted the call to Objective-C in Firebase 11 with no change in behavior.

paulb777 avatar Aug 31 '24 23:08 paulb777

We're considering adding two alternative APIs:

  1. A published property that’s an enum:
  • unknown
  • loggedIn(User)
  • loggedOut
  1. An async API that waits for the keychain to be read before returning the current user

paulb777 avatar Sep 01 '24 16:09 paulb777

@paulb777 could be that even the user data is available, the profile data is stalled or outdated? https://github.com/firebase/firebase-ios-sdk/issues/13571

jesus-mg-ios avatar Sep 04 '24 21:09 jesus-mg-ios

@paulb777 can we expect a fix in the next version ?

yarodevuci avatar Sep 05 '24 04:09 yarodevuci

There are two problems discussed in this issue.

  • One is that the currentUser API is inconsistent at app startup. That has always been an issue that we're exploring alternative APIs in a future release.
  • The other is that the recommended workaround for the first issue is to use a listener. There is a report that the listener is not working correctly, but we have not reproduced that issue.

We don't yet have a plan for either of these.

paulb777 avatar Sep 05 '24 14:09 paulb777

There are two problems discussed in this issue.

  • One is that the currentUser API is inconsistent at app startup. That has always been an issue that we're exploring alternative APIs in a future release.
  • The other is that the recommended workaround for the first issue is to use a listener. There is a report that the listener is not working correctly, but we have not reproduced that issue.

We don't yet have a plan for either of these.

if this is true @paulb777 , then when I request the currentUser after some time (e.g., 2 minutes after app launch), it should be updated. However, it seems that this is not always the case. For example, after changing the displayName within the same app, and restart it again, sometimes the displayName reverts to the old one and no changes are made along the app lifecycle to this property, even the reload function for the current user doesn't always work as expected, and only logging out and back in resolves it.

jesus-mg-ios avatar Sep 05 '24 15:09 jesus-mg-ios

@jesus-mg-ios A repro case of a change getting reverted would be helpful

paulb777 avatar Sep 07 '24 00:09 paulb777

@paulb777 I think there's actually a change in logic (or unintended consequence) going on between 10.29.0 and 11.0.0. With the use of @synchronized in the previous 10.x codebase, the cached user is being read from disk and stored as currentUser before configure completes, which allows us to make use of the cached authenticated user.

In 11.x, configure completes without the authenticated user (even if there's one cached on disk). If developers have been creating an anonymous user based on the state of current user after configure completes, we'll improperly create another anonymous user.

bryandubno avatar Sep 17 '24 16:09 bryandubno

Any update on this? I cannot get the user from auth.currentUser or auth.getStoredUser on version 11.2.0.

Pigpocket avatar Sep 30 '24 07:09 Pigpocket

I had to downgrade until 11.x mimics the 10.x behavior

bryandubno avatar Sep 30 '24 09:09 bryandubno