miz-k
miz-k

Reputation: 995

Cloud Firestore Security Rule exists() doesn't work

As shown below, I want to set up a security rule when a user exists in the "users" node, the user can access the "email" node. Meeting the case, I used builtin exists() function but it doesn't seem working correctly. I've just been getting "Missing or insufficient permissions." Just in case, the user exists under the "users" node for sure.

This issue still occurs when using the get() function, where incorporating this issue(Firestore security rule get() not work)

I'm totally not sure why this rule doesn't work. Would be appreciated if you could give me any help.

service cloud.firestore { 
  match /databases/{database}/documents {
    match /emails/{email} {
      allow read, write: if exists(/databases/$(database)/documents/users/$(request.auth.uid));
    }

    match /users/{userId} {
      allow read, write: if request.auth != null;
    }
  }
}

Upvotes: 2

Views: 1124

Answers (2)

android51130
android51130

Reputation: 1115

When you creating signIn options, you also should set "requestIdToken" to options builder to then use it in Firestore Rules like "request.auth.uid":

GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(getString(R.string.default_web_client_id))
            .requestEmail()
            .build()

When you get GoogleSignInAccount(for example) in your activity's onActivityResult, then you have to set it to Firestore singleton instance:

 private fun firebaseAuthWithGoogle(acct: GoogleSignInAccount) {

    AppState.googleAccount = acct

    val mAuth = FirebaseAuth.getInstance()

    val credential = GoogleAuthProvider.getCredential(acct.idToken, null)

    mAuth.signInWithCredential(credential)
            .addOnCompleteListener(this, object : OnCompleteListener<AuthResult> {

                override fun onComplete(@NonNull task: Task<AuthResult>) {

                    when (task.isSuccessful) {

                        true -> // good, continue from this line
                        false -> showError("error sign in with google account")
                    }
                }
            })
}

Upvotes: 0

dubace
dubace

Reputation: 1621

Did you try use get() instead of exists()? For me this is working

allow read, write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data != null

Upvotes: 1

Related Questions