Search code examples
google-cloud-firestorefirebase-authenticationfirebase-security

Firestore PHP SDK using Auth Rule setup


I am new to Firebase, right now i want to try Firestore php SDK and implement firestore auth rule. Current code below is work fine

use Google\Cloud\Firestore\FirestoreClient;

 $db = new FirestoreClient();
 $db->collection('mycollectionname')
    ->document('mydocumentname')
    ->set(['name'=>'aaa','value'=>'111');

Firestore auth rule

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {

      // before change
      allow read, write: if true;

      // after change
      allow read, write: if request.auth.uid != null;

    }
  }
}

After change true to request.auth.uid != null, its give me error:

{ "error": { "code": 403, "message": "Missing or insufficient permissions.", "status": "PERMISSION_DENIED" } }

I can figure out to get user data like : email & password or user id token, how to solve above error using user data?


Solution

  • I just found it, maybe useful for anyone.

    on file use Google\Cloud\Firestore\Connection\Grpc I made some change :

    ......
    ......
    
        private function addRequestHeaders(array $args)
        {
            $args += [
                'headers' => []
            ];
    
            $args['headers']['google-cloud-resource-prefix'] = [$this->resourcePrefixHeader];
    
    
            /////////  CODE THAT I ADD ///////////
            if(session('user_token'))
            {
                $args['headers']['Authorization'] = ['Bearer '.session('user_token')];
            }
            /////////  CODE THAT I ADD ///////////
    
            // Provide authentication header for requests when emulator is enabled.
            if ($this->isUsingEmulator) {
                $args['headers']['Authorization'] = ['Bearer owner'];
            }
    
            return $args;
        }
    

    Using laravel, I made it to check the session, to add a Bearer token on header. After that using example above i added a session before the Firestore function was used

    use Google\Cloud\Firestore\FirestoreClient;
    
     /// adding session
     session(['user_token'=>'eyJhbGciOiJSUzI1................']);
    
     $db = new FirestoreClient();
     $db->collection('users')
        ->document('test@gmail.com')
        ->set(['name'=>'aaa','value'=>'111');
    

    In the auth rule I can also make document rules according to the user's email name, where the user's email can be obtained with the token id that was added before. Example:

    rules_version = '2';
    service cloud.firestore {
      match /databases/{database}/documents {
        match /users/{email} {
           allow read, write: if email == request.auth.token.email;
        }
      }
    }