In an Angular PWA I'm using firebase security rules to restrict access to nearly all of my data to authenticated users. In an auth-guard I check if the user is authenticated and if not, the user is signed in anonymously (signInAnonymously()
) so I ensure that I have a user-id that I can use to flag objects that the user creates. This flag is necessary so I know if the user is the creator and if he is allowed to delete his own comment.
This all works fine - also when I lose connectivity. But if I close the PWA, enable flight-mode and then open the PWA (without connectivity) - signInAnonymously
returns an error (because of course the user cannot be signed in on the server). I on the other hand expect to either get the user from LocalStorage / IndexedDb
returned or that after opening the app the onAuthStateChanged
-Event fires with the locally stored user.
None of this happens (although I see, that the user is in fact stored in indexeddb by Firebase). Docs: Authentication State Persistence also state, that
For a web application, the default behavior is to persist a user's session even after the user closes the browser.
What am I missing? What should I do differently to achieve my goal of:
The PWA should behave like a native app. If I have no connectivity, as I use
enableIndexedDbPersistence()
for Firestore, the app should load whichever data is in cache and as soon as connectivity is restored, the app should seamlessly use online data.
Edit:
This is the code of my AuthService
:
@Injectable()
export class AuthService {
private authState: User = null;
private _isAuthenticated = new ReplaySubject<boolean>();
public isAuthenticated$ = this._isAuthenticated.asObservable();
public get userId() {
if (this.authState)
return this.authState.uid;
throw "No User-Id!";
}
constructor(private fAuth: Auth) {
onAuthStateChanged(this.fAuth, async (user) => {
AdminConsoleDialogComponent.addLogLine(`onAuthStateChanged: ${user?.uid}`);
this.authState = user;
try {
if (!this.authState) {
this.authState = (await signInAnonymously(this.fAuth)).user;
}
} catch (e) {
AdminConsoleDialogComponent.addLogLine(`onAuthStateChanged Error: ${e}`);
console.error(e);
} finally {
this._isAuthenticated.next(this.authState != null);
}
});
}
}
Output as follows (from addLogLine
-Calls):
onAuthStateChanged: tszjaBTtltVo9XV5B4kHAHnNNt22
onAuthStateChanged: undefined
onAuthStateChanged Error: FirebaseError: Firebase: Error (auth/internal-error).
onAuthStateChanged: undefined
onAuthStateChanged: D54ENbliWVhyYc9izXjFbtzXhUG2
I just realized that I even get a new anonymous user.
I cannot pinpoint it exactly but after deleting node_modules/package-lock.json (and with this updating @angular/* packages from 12.2.5
to 15.2.7
) it seems to work fine. There must have been a bugfix recently.