Getting the user id from a database trigger in Cloud Functions for Firebase?

11,856

Solution 1

Ever since Firebase functions reached version 1.0, this behavior is no longer undocumented but has sligtly changed. Be sure to read the docs.

Context has been added to cloud functions and you can use it like this

  exports.dbWrite = functions.database.ref('/path/with/{id}').onWrite((data, context) => {
  const authVar = context.auth; // Auth information for the user.
  const authType = context.authType; // Permissions level for the user.
  const pathId = context.params.id; // The ID in the Path.
  const eventId = context.eventId; // A unique event ID.
  const timestamp = context.timestamp; // The timestamp at which the event happened.
  const eventType = context.eventType; // The type of the event that triggered this function.
  const resource = context.resource; // The resource which triggered the event.
  // ...
});

Solution 2

UPDATED ANSWER (v1.0.0+):

As noted in @Bery's answer above, version 1.0.0 of the Firebase Functions SDK introduced a new context.auth object which contains the authentication state such as uid. See "New properties for user auth information" for more details.

ORIGINAL ANSWER (pre v1.0.0):

Yes, this is technically possible, although it is not currently documented. The uid is stored with the event.auth object. When a Database Cloud Function is triggered from an admin situation (for example, from the Firebase Console data viewer or from an Admin SDK), the value of event.auth is:

{
  "admin": true
}

When a Database Cloud Function is triggered from an unauthenticated reference, the value of event.data is:

{
  "admin": false
}

And finally, when a Database Cloud Function is triggered from an authed, but not admin, reference, the format of event.auth is:

{
  "admin": false,
  "variable": {
    "provider": "<PROVIDER>",
    "provider_id": "<PROVIDER>",
    "user_id": "<UID>",
    "token": {
      // Decoded auth token claims such as sub, aud, iat, exp, etc.
    },
    "uid": "<UID>"
  }
}

Given the information above, your best bet to get the uid of the user who triggered the event is to do the following:

exports.someFunction = functions.database.ref('/some/path')
  .onWrite(event => {
    var isAdmin = event.auth.admin;
    var uid = event.auth.variable ? event.auth.variable.uid : null;

    // ...
});

Just note that in the code above, uid would be null even if isAdmin is true. Your exact code depends on your use case.

WARNING: This is currently undocumented behavior, so I'll give my usual caveat of "undocumented features may be changed at any point in the future without notice and even in non-major releases."

Share:
11,856
Bilal Soomro
Author by

Bilal Soomro

Updated on June 16, 2022

Comments

  • Bilal Soomro
    Bilal Soomro about 2 years

    In the example below, is there a way to get the uid of the user who wrote to /messages/{pushId}/original?

    exports.makeUppercase = functions.database.ref('/messages/{pushId}/original')
    .onWrite(event => {
      // Grab the current value of what was written to the Realtime Database.
      const original = event.data.val();
      console.log('Uppercasing', event.params.pushId, original);
      const uppercase = original.toUpperCase();
      // You must return a Promise when performing asynchronous tasks inside a Functions such as
      // writing to the Firebase Realtime Database.
      // Setting an "uppercase" sibling in the Realtime Database returns a Promise.
      return event.data.ref.parent.child('uppercase').set(uppercase);
    });
    
  • alalonde
    alalonde about 7 years
    Any reason why there isn't a public API for this? Seems like a reasonable use case (we're exploring FB as a backend and this was a major outstanding question).
  • skwny
    skwny almost 7 years
    Any indications that this will change or stay? This is ideal for my use case but I don't want to use it if could still change.
  • Edmond C
    Edmond C over 6 years
    Added a bug/request to document this and make it an official public API github.com/firebase/firebase-functions/issues/133
  • cutiko
    cutiko over 6 years
    In case somebody else is wondering this is the entire object when the event.auth is not from admin: pastebin.com/CgyivDRm
  • taykay08
    taykay08 over 5 years
    Looks like the syntax has changed with the release of v1.0.0, and it's now documented: firebase.google.com/docs/functions/beta-v1-diff
  • jwngr
    jwngr over 5 years
    @taykay08 - Thanks! I've updated my answer to include this new information.