Search code examples
firebasegoogle-cloud-firestorefirebase-security

Firebase Security: [WriteStream]: Stream closed


I register/login in my app and firebase send me a sms code for verify. my app return a page about verification successfuly when I verify to code. then my app have to go to homepage and return to sites I subscribed. but I got "write error" from firebase security.


W/Firestore( 6596): (24.4.3) [WriteStream]: Stream closed with status: Status{code=PERMISSION_DENIED, description=Missing or insufficient permissions., cause=null}.
W/Firestore( 6596): (24.4.3) [Firestore]: Write failed at subscribers/{subscriberId}: Status{code=PERMISSION_DENIED, description=Missing or insufficient permissions., cause=null}

my security rules.

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    
        allow read: if isSignIn() && 
      request.auth.uid == resource.data.userId && 
      resource.data.role == "Admin";
        
      allow get, write: if isSignIn() && 
      request.auth.uid == resource.data.userId && 
      request.auth.token.phone_number == resource.data.phone &&
      resource.data.role == "Subscriber";
        
            match /sites/{site} {
            allow read, write: if isSignIn();
          match /messages/{message}{
          allow read, write: if isSignIn();
      }  
    }
  } 
  
  function isSignIn(){
    return request.auth.uid != null;
  }
}

Solution

  • There is no statement match subscribers/{subscriberId} path because unlike RTDB rules Firestore rules do not cascade, see offical video, So just add statement to match the path.

    rules_version = '2';
    service cloud.firestore {
      match /databases/{database}/documents {
        match subscribers/{subscriberId} {
          allow read: if isSignIn() && 
          request.auth.uid == resource.data.userId && 
          resource.data.role == "Admin";
            
          allow get, write: if isSignIn() && 
          request.auth.uid == resource.data.userId && 
          request.auth.token.phone_number == resource.data.phone &&
          resource.data.role == "Subscriber";
         }
                match /sites/{site} {
                allow read, write: if isSignIn();
              match /messages/{message}{
              allow read, write: if isSignIn();
          }  
        }
      } 
      
      function isSignIn(){
        return request.auth.uid != null;
      }
    }