2

I'm trying to make a simple messaging app. In the process, I want to use firebase's cloud function feature for functions that should not be carried out client-side for the sake of security.

Many of the functions I want to be called whenever the user wants. The way I'm trying to do it now is by having clients push little 'function request' objects under a single parent so that the onWrite function will fire off and I can parse the request object to execute the function (The reason I'm not using http functions is because I want some way to securely know which user has made the request).

The problem is I can't find a way in firebase's documentation to know which user wrote the data.

in index.js I have

exports.requestFunction = functions.database.ref('/function-
requests/{pushId}')
.onWrite(event => {
// Parse event.data.val() for things like the function name and its
// parameters. Then actually call the function.
// Ideally I would also be able to parse event somehow to find the user
// who saved the data.
});

Please note that I have considered including the user id as a parameter, but that's too unsafe as any user can pretend to be another user by giving a different uid.

AL.
  • 36,815
  • 10
  • 142
  • 281

3 Answers3

0

You could write a Firebase Database Rule that only allows the user to write their own user id in a specific field, then pass it up as a parameter.

ex.

"user": {
  ".validate": "newData.val() === auth.uid"
},
alecschrader
  • 371
  • 3
  • 8
0

You have two choices. First, you can make the UID part of the database write path, the use a security rule to ensure that only an authenticated rule can write to that path. Consider the Database trigger wildcard path "/commands/{uid}/{pushid}" along with the following security rule:

"commands": {
    "$uid": {
        ".read": false,
        ".write": "$uid === auth.uid"
    }
}

Only an authenticated user can effectively write to their own area of the database under /commands/{uid}. You can grab the matched UID wildcard in the function like this: const uid = event.params.uid

Consider watching my talk at Google I/O 2017 where I use this strategy to build a turn-based game.

You can also ask the database trigger event the UID that generated the write, as described in this other question, though it is not documented (or supported).

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
0

First you can read more about security rules in here, (different with other links "security/database")

Make sure in the data that you want to save to the database contains field for example "user_id", this field will be checked with the auth.uid whether it's same or not.

make your database rule like this :

{
 "rules": {
   ".read": true,
   "function-requests": {
      "$pushId" :{
          ".write": "newData.child('user_id').val() == auth.uid"
      }
    }
  }
}

After that you can proceed your cloud function without worries

Faruk
  • 5,438
  • 3
  • 30
  • 46