2

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?

  • using this post its gave me result i want: https://stackoverflow.com/questions/54808277/simple-and-dirty-firestore-authentication-rule[link] But i want using current Firestore SDK, that parse auth data on **FirestoreClient()** – Emanuel Riolan Apr 05 '20 at 07:25

2 Answers2

0

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;
    }
  }
}
0

Hellow,

If you want implement FirestoreClient PHP Library in your backend, you should use a service account to allow your backend go through firestore rules, this way you can control users flow (with rules) and give complete access or limited access to your own backend code. You can see how to set up a service account in Google's quicstart documentation.

In this process you might have some issue while trying to configure the path to your service account key file. Which might throw this error:

Google\Cloud\Core\Exception\ServiceException: 
{ 
    "message": "Missing or insufficient permissions.", 
    "code": 7, 
    "status": "PERMISSION_DENIED"
}

If this happens to you see my response in this stackoverflow thread.

I hope it helps you and everyone having the same issue.

GaelCodes
  • 21
  • 3