javascriptnode.jsfirebasegoogle-cloud-firestoregoogle-cloud-functions

Firebase Triggered Cloud Function is not aware of user


I have integrated a payment system to my Firebase app and their system sends a POST request to my backend. I handle that request as below:

app.post("/subscription", (req, res) => {
  const {data, signature} = req.body;
  const decodedJson = JSON.parse(Buffer.from(data, "base64"));
  return admin
      .firestore()
      .collection("subscriptions")
      .doc(decodedJson.order_id)
      .set({
        subscriptionDate: admin.firestore.FieldValue.serverTimestamp()})
      .then(() => {
        return res.status(200).send("Subscription created");
      })
      .catch((error) => {
        throw new Error(error);
      });
});

Then I have another function that is triggered whenever a new document is created under "subscriptions" collection:

exports.checkPaymentStatus = functions.firestore
    .document("subscriptions/{subscriptionId}")
    .onCreate((snap, context) => {
        return axios.post("https://paymentsystem.com/api/1/get-status", {
          data: dataParam,
          signature: signature,
        })
        .then((response) => {
          if (response.data.status === "success") {
            const batch = admin.firestore().batch();

            batch.update(admin.firestore().collection("subscriptions")
            .doc(snap.id), {subscriberId: context.auth.uid});

            batch.update(admin.firestore().collection("users")
            .doc(context.auth.uid), {
              isPro: true,
              subscribedDate: admin.firestore.FieldValue.serverTimestamp(),
            });
            }
          })
        .catch((error) => {
          console.error("Error occurred:", error);
          });
      });

However, it gives error "Error occurred: TypeError: Cannot read properties of undefined (reading 'uid')". It is due to context.auth.uid variable. How can I solve this?

I try to update the field value of user document. But, I need to access user document.


Solution

  • You're using gen 1 Cloud Functions triggers for Firestore, and there is no context.auth parameter available in those. See:

    If you migrate the code to gen 2 of Cloud Functions, the information about the user who triggered the function is actually available for the onDocument...WithAuthContext trigger. I recommend having a look at the documentation on Cloud Firestore function triggers and Access user authentication information, which also contain this code sample.

    import { onDocumentWrittenWithAuthContext } from "firebase-functions/v2/firestore"
    
    exports.syncUser = onDocumentWrittenWithAuthContext("users/{userId}", (event) => {
        const snapshot = event.data.after;
        if (!snapshot) {
            console.log("No data associated with the event");
            return;
        }
        const data = snapshot.data();
    
        // retrieve auth context from event
        const { authType, authId } = event;
    
        let verified = false;
        if (authType === "system") {
          // system-generated users are automatically verified
          verified = true;
        } else if (authType === "unknown" || authType === "unauthenticated") {
          // admin users from a specific domain are verified
          if (authId.endsWith("@example.com")) {
            verified = true;
          }
        }
    
        return data.after.ref.set({
            created_by: authId,
            verified,
        }, {merge: true}); 
    });