Context: In my iOS game, I'd like to allow users to play without logging in (authenticating anonymously in Firebase to save user data), but also give them the option to login with Facebook to unlock additional gameplay.
I'm attempting a modification of this post, replacing Twitter logins with anonymous logins:
"users": {
"$userid": {
// Require the user to be logged in, and make sure their current credentials
// match at least one of the credentials listed below, unless we're creating
// a new account from scratch.
".write": "auth != null &&
(data.val() === null ||
(auth.provider === 'facebook' && auth.uid === data.child('facebook/id').val() ||
(auth.provider === 'anonymous' && auth.uid === data.child('anonymous/id').val()))"
}
}
I'm confused how the transition will work with these rules. In particular, say:
A user authenticates anonymously, and is able to create a canonical user record with their anonymous uid stored under
users/"$userid"/anonymous/id
. This is allowed because the user is authenticated and the user object is being set for the first time (auth != null && data.val() === null
).Any subsequent writes to
users/"$userid"/
are allowed because the authenticated user's anonymous id is stored in the user tree (auth != null && (auth.provider === 'anonymous' && auth.uid === data.child('anonymous/id').val())
).The user logs into facebook. Now
authData
contains the facebook uid, which has not yet been written tousers/"$userid"/facebook/id
. Writes to that location fail because security rules don't allow it.
So the anonymous user doesn't have access to the facebook uid until after facebook authentication completes. At that point, it's too late to write to users/"$userid"/facebook/id
because the authenticated user is now a facebook user and doesn't have permission to write there.
Am I missing something? Any ideas on how to remedy this situation?