firebase / firebase/firebase-js-sdk

Possible race condition when calling signInAnonymously immediately after getAuth()

Open
#7,049 18 comments 1 reaction 0 assignees View on GitHub
api: auth needs-attention question v9
Dominant language
TypeScript
Stars
5.1k
Forks
1k
Avg merge
2d 21h
Merged PRs (30d)
37

Description

### [REQUIRED] Describe your environment

* Operating System version: iOS 16.3.1
* Browser version: Safari 16.3.1
* Firebase SDK version: 9.15.0
* Firebase Product: auth

### [REQUIRED] Describe the problem

#### Steps to reproduce:
On loading, our React app immediately loads a component that does the following:
* calls `getAuth()`
* runs a hook to setup `onAuthStateChanged`
* once `onAuthStateChanged` handler is called for 1st time we check for a valid user object
* If no valid user object exists call `signInAnonymously`

What we're observing in our production env **on an irregular basis** is that the `onAuthStateChanged` is called multiple times with different a `uid` everytime.
More specifically, the 1st time app is opened on a "clean" browser, there is no persisted user `uid` for Firebase auth so the `onAuthStateChanged` handler fires with `null` user, we perform `signInAnonymously`, and `onAuthStateChanged` is fired again with valid `uid`.
Next time app is opened (few mins later) we can see `onAuthStateChanged` fired mutliple times in sequence with an alternating `uid` provided - one time the previous `uid` from the first-time open and a new `uid`.

Expectation is that the previous session's `uid` will be provided OR that a new `uid` be created but would not change - `onAuthStateChanged` should not be called with multiple diff values of `uid` for the same browser session.
#### Relevant Code:

```javascript
export default function ClientAuthProvider() {
const [user, setUser] = useState(null);
const auth = getAuth(firebaseApp);

useEffect(() => {
const unsub = onAuthStateChanged(auth, user => {
if (user) {
setUser(user);
} else {
signInAnonymously(auth)
.catch(error => {
setUser(null)
})
}
})
return () => {
unsub();
}
}, []);

}
```

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 calling `signInAnonymously` too early would cause a race condition in auth service to generate two `uid` for same browser?
This issue looks similar in some ways to the issue described in https://github.com/firebase/firebase-js-sdk/issues/6827

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.