GaryO
GaryO

Reputation: 6338

Firebase realtime database rules don't allow anonymous-authenticated users

I have a simple web app with a Firebase realtime database, and Firebase auth. My db rules look like this:

{
  "rules": {
    "users": {
      "$uid": {
        ".write": "$uid === auth.uid",
        ".read": "$uid === auth.uid"
      }
    }
  }
}

so only an authenticated user can read/write their own user record. But when I allow anonymous authentication, anonymous users cannot write their own profile record even though they have a UID and are writing to the correct record. I get a Firebase "PERMISSION DENIED" error.

It all works fine with email+password-authenticated users. To be clear, logging in with email+password provider works fine, but logging in anonymously (with the anonymous provider) does not allow write access.

I am testing this in the onAuthStateChanged() callback, so I know the user is valid:

onAuthStateChanged(auth, async (user) => {
  try {
    // ignore token refresh events
    if (user && currentUID === user.uid)
      return

    if (user) {
      currentUID = user.uid
      // Create user record and update last login
      const db = getDatabase()
      const userRef = ref(db, 'users/' + user.uid)
      console.log(JSON.stringify(user))
      if (true) { // <<<<<<<<<<< THIS IS WHERE I GET "permission denied"
        update(userRef, {
          email: user.email || '-none-',
          uid: user.uid,
          lastLogin: serverTimestamp()
        })
          .catch(err => handleError(err))
      }
      on_sign_in(user)
    } else {
      currentUID = null
      // User is signed out
      on_sign_out()
    }

  } catch (error) {
    handleError(error, error.message)
  }
})

Upvotes: 1

Views: 161

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598740

I tried to reproduce the problem, but the SDK and code seem to work as expected for me. I'm posting my minimal non-repro here, in hopes it'll help you find the difference between your non-working code and my working example.

My code:

onAuthStateChanged(auth, (user) => {
  if (user) {
    console.log("User signed in", user);

    const dbRef = ref(db, "77153837");
    const userRef = child(dbRef, user.uid);

    set(userRef, false).then(() => {
      console.log("Wrote to db");
    });
  }
})
signInAnonymously(auth);

And the rules I use:

{
  "rules": {
    "77153837": { 
      "$uid": { 
        ".write": "$uid === auth.uid" 
      } 
    }
  }
}

In these the 77153837 is the ID of the question you posted here. It has no meaning for the problem beyond that.

You can see the entire code and run it here: https://stackblitz.com/edit/firebase-v9-rtdb-anonymous-writes

Upvotes: 0

Related Questions