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.
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});
});