-
Notifications
You must be signed in to change notification settings - Fork 928
Possible race condition when calling signInAnonymously immediately after getAuth() #7049
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
Comments
Thanks for reporting this. I tried modifying the demo app in and could not repro this issue. I added firebase-js-sdk/packages/auth/demo/src/index.js Line 1749 in 547348b
We do await on the initializationPromise here -
2 more followups:
|
Hi @prameshj, I think the scenario for this issue is a little different than originally described.
Update:
Could it be that in case of Safari/Webkit Auth loses some persisted data that causes this "refresh" ? An important point I forgot to mention in the OP is that our Firebase app opens as an iFrame over a "hosting" website so it'll be considered a 3rd party domain by the browser.
As to browsers/devices:
|
This is very weird - Does this happen while they are on the web app still, i.e no page refresh? It is possible that there is some cross-origin storage access at play here. So, the hosting website is domain1. Your firebase app is domain2 and in domain1, you open an iframe to domain2 (where the onAuthStateChanged callbacks are invoked), correct? Are you using Local Storage persistence by any chance? I wonder if this is what happens:
There is some special case in Local Storage persistence for Safari/iOS + iframe -
|
Hey @shaibt. 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! |
Hey @prameshj:
You are correct - the Firebase app is only contained inside the iframe for domain2.
We don't set any special config settings during Firebase (or Firebase Auth) init - just plain default settings. What is the default persistence method? Does Firebase auth persist data in local storage? In our app, we do use local storage for persisting several app variables and indeed in Safari they don't get retained for very long - not longer than a few hours. Seems that Safari in this cross domain configuration will clean the cross domain iframe's local storage from time-to-time and we can see this as the variables are not persisted over long periods of time as in Chrome. However, the only Firebase related entry in local storage that I can see is |
With
If indexDb is not available, it falls back to local storage. firebase-js-sdk/packages/auth/src/core/persistence/persistence_user_manager.ts Lines 116 to 133 in fdd4ab4
Is it possible that indexDB is not available in the Safari version you are using? Do you see any indexDB/local storage entry like:
The code I reference will get invoked upon local storage events, so if Safari does wipeout the storage entry, that will explain the issue you see. |
In Safari dev tools I cannot see the I wasn't sure if its browser policy or the dev tools only showing indexedDB for the main/hosting domain1 and not showing for the Firbebase app's domain2. So I added some code to our firebase app to open the IndexedDB named So if auth is persisted in indexedDB why is a local storage event refreshing auth? PS: In Chrome, under same exact scenario I can clearly see the auth entry in indexedDB under domain2. |
Hey @prameshj - any updates/ideas of how we can work around this Safari issue? |
This is likely the case, Safari 16.1+ does session storage partitioning, it probably extends to local and indexedDB storage too..
yea, if you are using indexedDB, then the local storage code path I pointed out is likely not suspect. Are you seeing indexedDb entries in the same Safari version that sometimes sees the race condition issue? |
Cannot inspect indexedDB in dev tools because for some reason Safari will only show the main domain's indexedDB. |
You're right.. looks like indexedDb doesn't have storage event observer support - https://stackoverflow.com/questions/33237863/get-notified-when-indexeddb-entry-gets-changed-in-other-tab It is possible to poll.. which is what we do in the auth persistence implementation -
Which Safari version are you seeing the issue with? Also, as an aside, how do you handle the cases where a user logouts from the app? That will still call onAuthStateChanged and create a new anonymous user. That wouldn't cause this race condition (unless there is some sign out code path triggering erroneously), but it would lead to a lot of zombie anonymous users (if the user closes the page shortly after signing out). |
Seeing it across all Safari 16.X versions in iOS & OSX. There is no logout option for the app. To keep things simple:
|
Thanks for the additional info! We will try to repro this at our end with additional logs. |
Hi @prameshj, just wondering if you have any update on this case. |
We haven't been able to get a repro yet. cc @jbalidiong |
I had the same problem with Safari 17.1.2. problem code export class FirebaseService {
constructor(
private afa: AngularFireAuth,
) {}
public initializeFirebase(): void {
this.afa.authState.subscribe(user => {
// **not get here**
});
this.afaLogin();
}
public afaLogin(): void {
this.afa.signInAnonymously().catch(()=> {
setTimeout(() => {
this.afaLogin();
}, 1000);
});
}
} modified code export class FirebaseService {
constructor(
private afa: AngularFireAuth,
) {}
public initializeFirebase(): void {
this.afa.signInAnonymously().then(() => {
this.afa.authState.subscribe(user => {
// **get here**
});
}).catch(()=> {
setTimeout(() => {
this.initializeFirebase();
}, 1000);
});
}
} |
Hi @prameshj, |
[REQUIRED] Describe your environment
[REQUIRED] Describe the problem
Steps to reproduce:
On loading, our React app immediately loads a component that does the following:
getAuth()
onAuthStateChanged
onAuthStateChanged
handler is called for 1st time we check for a valid user objectsignInAnonymously
What we're observing in our production env on an irregular basis is that the
onAuthStateChanged
is called multiple times with different auid
everytime.More specifically, the 1st time app is opened on a "clean" browser, there is no persisted user
uid
for Firebase auth so theonAuthStateChanged
handler fires withnull
user, we performsignInAnonymously
, andonAuthStateChanged
is fired again with validuid
.Next time app is opened (few mins later) we can see
onAuthStateChanged
fired mutliple times in sequence with an alternatinguid
provided - one time the previousuid
from the first-time open and a newuid
.Expectation is that the previous session's
uid
will be provided OR that a newuid
be created but would not change -onAuthStateChanged
should not be called with multiple diff values ofuid
for the same browser session.Relevant Code:
This wasn't reproducible in testing envs and happens only on occasion on production.
Could it be that calling
getAuth()
multiple times would create more than 1 instance of the auth service? Could it be that callingsignInAnonymously
too early would cause a race condition in auth service to generate twouid
for same browser?This issue looks similar in some ways to the issue described in #6827
The text was updated successfully, but these errors were encountered: