invrt
invrt

Reputation: 709

Cloud function trigger on document update

I am trying to fire my cloud function if theres a document update on users/{userId}

I have a signIn method that's fired everytime a user logs in

signin: (email, password, setErrors) => {
    firebase
      .auth()
      .signInWithEmailAndPassword(email, password)
      .then(() => {
        const isVerified = firebase.auth().currentUser.emailVerified
        const userUid = firebase.auth().currentUser.uid
        const db = firebase.firestore()
        if (isVerified) {
          db.collection('/users')
            .doc(userUid)
            .update({ isVerified: true })
        }
      })
      .catch(err => {
        setErrors(prev => [...prev, err.message])
      })
  },

Nothing fancy, aside from the basic log in stuff, it also checks if the user has verified their email, if it is verified it will update the collection for that user. Everything is working as intended here.

However I can't seem to get my cloud function to fire.

Basically, it's listening for changes on ther user collection. If users/{userId} document has isVerified and the user email address ends with xxxx it should grant them admin privledges.

exports.updateUser = functions.firestore.document('users/{userId}').onUpdate((change, context) => {
  const after = change.after.data()
  if (after.isVerified) {
    firebase.auth().onAuthStateChanged(user => {
      if (user.emailVerified && user.email.endsWith('@xxxx')) {
        const customClaims = {
          admin: true,
        }
        return admin
          .auth()
          .setCustomUserClaims(user.uid, customClaims)
          .then(() => {
            console.log('Cloud function fired')
            const metadataRef = admin.database().ref('metadata/' + user.uid)
            return metadataRef.set({ refreshTime: new Date().getTime() })
          })
          .catch(error => {
            console.log(error)
          })
      }
    })
  }
})

Right now the function is not firing, any ideas?

Upvotes: 0

Views: 282

Answers (2)

Frank van Puffelen
Frank van Puffelen

Reputation: 600006

Code in Cloud Functions runs as an administrative account, which cannot be retrieved with the regular Firebase Authentication SDK. In fact, you should only be using Firebase Admin SDKs in your Cloud Functions code, in which the onAuthStateChanged method doesn't exist.

It's not entirely clear what you want this code to do with the user, but if you want to check whether the user whose uid is in the path has a verified email address, you can load that user by their UID with the Admin SDK.

To ensure that the uid in the path is the real UID of the user who performed the operation you can use security rules, as shown in the documentation on securing user data.

Upvotes: 1

Codigo Morsa
Codigo Morsa

Reputation: 840

I support what Frank said.

You can fetch users with admin in this way:

if (after.isVerified) {
  admin.auth().getUser(userId)
    .then((userData) => { ... 

Upvotes: 1

Related Questions