If you look at the screenshot you can see that the simulated test passes:
It restricts adding user data to the users node if the uid does not match.
You can see the location is:
/users/6OCBYNh3CTammMWrCjX0F003zab2
In other words:
/users/$uid
When I try to do this from code, I get a permission denied error:
private async addNewUserToFirebase(user: firebase.User): Promise<void> {
console.log('adding user to Firebase', user);
try {
const ref = this.db.list('/users');
await ref.update(user.uid, {email: 'test@test.com'});
} catch (error) {
console.error('Unable to add user to firebase db', error);
}
}
@firebase/database: FIREBASE WARNING: update at /users/6OCBYNh3CTammMWrCjX0F003zab2 failed: permission_denied
However, if I change the rule to simply
".write": "auth != null"
then it works. So why is it failing when I try to match the uid?
NOTE
I have also tried:
const refAccount = this.db.list('/users');
await refAccount.update(`/${user.uid}`, {email: "test@test.com");
and get the same error.
I have tried with multiple users from both the simulator and code. The results are consistent.
Yet this question shows identical rules, and for that OP it works.
So this seems to be an issue with getRedirectResults()
Further testing has uncovered that this code works (with the rule userId === auth.id
):
this.angularFireAuth.onAuthStateChanged(user => {
firebase
.database()
.ref('users')
.child(user.uid)
.child('email')
.set('test@test.com');
});
but this does not, as the user is always null:
this.angularFireAuth.getRedirectResult().then(credential => {
firebase
.database()
.ref('users')
.child(credential.user.uid)
.child('email')
.set('test@test.com');
});
This still does not explain why sometimes auth.uid !== null
works.
But it seems I am not the only person with a null user on getRedirectResults()
as you can see here and there is an official bug report here