Reputation: 2409
I have difficulties returning a value using a callable firebase function, while the same code works fine when it is a httprequest.
So what I am doing, is getting some user data, then getting some other data (a list of vessels) and then only return the vessels the user has edit rights for. I am very sure the accessibleVessels
object holds some json data: I changed the function in a functions.https.onRequest
firebase function and it went fine.
exports.getFormData = functions.https.onCall( (data, context) => {
const uid = context.auth?.uid.toString;
try {
const user = admin.firestore().
doc("users/"+uid)
.get().then((doc: any) => {
return doc.data();
});
const vessels = admin.firestore().
collection("vessels").get()
.then(mapSnapshot((doc: any) => doc.data()));
const accessibleVessels = vessels.filter((vessel: any) => {
return user.hasEditRights.some((right: any) => {
return vessel.name === right;
});
});
return accessibleVessels;
} catch (error) {
console.log(error);
return {"error": true};
}
});
When I run this I get:
Data cannot be encoded in JSON. [Function (anonymous)]
Looking in the documentation I understand that I do need to return json or a promise. I read other answers about this (returning a promise) but don't see how this would work in my example: in the examples I find not much is done with the data, it's just returned. I want to put the data in variables instead of chaining everything, so I can combine both. How should I do this?
Upvotes: 1
Views: 1322
Reputation: 600126
The easiest way to fix this is using async
/await
:
exports.getFormData = functions.https.onCall(async(data, context) => { // 👈
const uid = context.auth?.uid.toString;
try {
const user = await admin.firestore() // 👈
.doc("users/"+uid)
.get().then((doc: any) => {
return doc.data();
});
const vessels = await admin.firestore() // 👈
.collection("vessels").get()
.then(mapSnapshot((doc: any) => doc.data()));
const accessibleVessels = vessels.filter((vessel: any) => {
return user.hasEditRights.some((right: any) => {
return vessel.name === right;
});
});
return accessibleVessels;
} catch (error) {
console.log(error);
return {"error": true};
}
});
I also recommend reading the MDN documentation on async
/await
, the Firebase documentation on sync, async, and promises and Doug's awesome series on JavaScript Promises in Cloud Functions.
Upvotes: 1