Learn JavaScript Promises (Pt.1) with HTTP Triggers in Cloud Functions - Firecasts
Why Stack Overflow recommends it
Stack Overflow users link it when a Cloud Function hangs, times out, or returns undefined because the promise is not returned or the function is not terminated properly.
Recommended by 6 people across 27 different months, 2018 to 2024.
What it is
A roughly 10-minute Firecast from the Firebase channel in which Doug Stevenson explains how JavaScript Promises work inside HTTP-triggered Cloud Functions. It shows why returning or chaining promises correctly matters and how functions fail in odd ways when it is done wrong.
What people said
Strong rec Renaud Tarnec · 2018-07 · Stack Overflow · on “Firebase Firestore update query doesn't execute because of the promise chaining. What am I doing wrong?”
I see two problems in your code: 1/ By doing return fStor.collection('users').get(); you are returning a QuerySnapshot [LINK] and not a DocumentSnapshot . See the doc of the get() method here [LINK] . The doc says that "A QuerySnapshot contains zero or more DocumentSnapshot objects representing the results of a query. The documents can be accessed as an array via the docs property or enumerated using the forEach method. " Therefore when, in then next then(), you do doc.data() you most probably get an error. 2/ The second problem, IMHO, is that you don't return anything in your charge function. Since, in a Cloud Function, you shall return a promise (or a value in specific cases) you should pr
Strong rec Renaud Tarnec · 2018-08 · Stack Overflow · on “Firebase cloud function shows error "No 'Access-Control-Allow-Origin' header is present on the requested resource."”
You should chain your promises, as follows: `var setAda = docRef.set({...}).then(() => {res.status(200).send(setAda);}).catch(err => {res.status(500).send(err);})`. I would suggest that you watch the two following "must see" videos from the Firebase team, about Cloud Functions and promises: [this video] and [LINK]
Strong rec Renaud Tarnec · 2019-06 · Stack Overflow · on “How can I implement a firebase set request within a call back”
In a Cloud Function you should use promises to handle asynchronous tasks (like the HTTP call to the stripe API, or the write to the Realtime Database). By default request does not return promises, so you need to use an interface wrapper for request, like request-promise [LINK] , and adapt your code along the following lines: const rp = require('request-promise'); exports.registerRestaurantPayout = functions.firestore.document('*********') .onCreate((paymentSnap, context) => { var authCode = paymentSnap.data().auth_code; var firstString = 'client_secret=**********='; var secondString = '&grant_type=authorization_code'; var dataString = firstString + authCode + secondString; var options = { me
Strong rec Renaud Tarnec · 2019-12 · Stack Overflow · on “Firebase functions/firestore not working and catch returning an empty object”
The get() [LINK] method of a CollectionReference returns a QuerySnapshot [LINK] which "contains zero or more DocumentSnapshot [LINK] objects representing the results of a query. The documents can be accessed as an array via the docs property or enumerated using the forEach() method". Therefore you should do as follows, calling map() on querySnapshot.docs : exports.test = functions.https.onRequest((request, response) => { admin .firestore() .collection('users') .get() .then(querySnapshot => { const arrUsers = querySnapshot.docs.map(element => element.data()); //return response.send(arrUsers); //You don't need to use return for an HTTPS Cloud Function response.send(arrUsers); //Just use respon
Strong rec Frank van Puffelen · 2020-03 · Stack Overflow · on “Error Database Triggered Cloud function with Promise”
Syntactically, you seem to be just be missing a return before fetchUserConversations(userId)... . So: return fetchUserConversations(userId).then(result=>{ To learn more about promises in Cloud Functions, you'd do best to study the Firebase documentation on sync, async, and promises [LINK] , and Doug Stevenson's excellent video series on using promises in Cloud Functions [this video] . A more fundamental problem with your code is that it doesn't do anything with the conversations it fetches for the user. It seems that you're trying to return them from the Cloud Function, but Cloud Functions that are triggered by a database write cannot return anything. Such Functions are triggered by a database wr
Recommends Andy Fusniak · 2018-04 · Stack Overflow · on “Slow, unreliable Firebase Cloud Functions”
I think you'll still face the same "sometimes it works" problem. See my answer on this page. Also check out Doug Stevenson's "Learn JavaScript Promises (Pt.1) with HTTP Triggers in Cloud Functions - Firecasts" as this is rather useful [this video]
Recommends Doug Stevenson · 2018-05 · Stack Overflow · on “Cloud Functions returned undefined, expected Promise or value”
Firestore triggers should return a promise the resolves when all asynchronous work is complete, or null if there was no work. Each one of your three cases needs to have a proper return value. if (!change.before) { // New document Created : add one to count return db.doc(docRef).get().then(snap => { return db.doc(docRef).update({numberOfDocs: snap.numberOfDocs + 1}); }); } else if (change.before && change.after) { // Updating existing document : Do nothing return null; } else if (!change.after) { // Deleting document : subtract one from count return db.doc(docRef).get().then(snap => { return db.doc(docRef).update({numberOfDocs: snap.numberOfDocs - 1}); }); } If you're going to spend time work
Recommends Renaud Tarnec · 2018-05 · Stack Overflow · on “How to clone a node to another path based on a reference value from the initial path on Google Cloud Functions?”
The following should work. const admin = require("firebase-admin"); .... .... exports.updateRoom = functions.database.ref('/doors/{MACaddress}').onWrite((change, context) => { const afterData = change.after.val(); // data after the write const roomPushKey = afterData.inRoom; const ins = afterData.ins; const updates = {}; updates['/rooms/' + roomPushKey] = ins; return admin.database().ref().update(updates); }).catch(error => { console.log(error); //+ other rerror treatment if necessary }); Here are some explanations: You get the roomPushKey by reading the "data after the write" as an object: roomPushKey = afterData.inRoom . You don't need to do roomPushKey.once('child_added').then() Once you
Recommends Renaud Tarnec · 2018-06 · Stack Overflow · on “firestore 1.0 not returning Firestore timestamp”
Your problem may come from the changes that were introduced in Firestore SDK recent release (version 5.0.3 for the JavaScript SDK): With this release the behavior for Date objects stored in Firestore changed: "timestamps stored in Cloud Firestore are read back as Firebase Timestamp objects instead of as system Date objects." You need to "update your code expecting a Date to instead expect a Timestamp", as follows: // Old: const date = snapshot.get('created_at'); // <- 'created_at' is an example of field name // New: const timestamp = snapshot.get('created_at'); const date = timestamp.toDate(); Also, you should chain your promises a bit differently as well as change the way you send the respo
Recommends Renaud Tarnec · 2019-03 · Stack Overflow · on “Sync data between Google Firestore and Google Sheets using Cloud Functions/Admin SDK”
I understand that you want to be able to call a Cloud Function from a Google Sheet in order to build an "end-to-end Sheets based interface" for Firestore. You can use the UrlFetchApp [LINK] Class to make a request to fetch the URL of an HTTP Cloud Function [LINK] . You Apps Script code would be like: function callSimpleHTTPCloudFunction() { const url = " [LINK] "; response = UrlFetchApp.fetch(url, { method: 'get' }) respObj = JSON.parse(response.getContentText()); Logger.log(respObj); } While your Cloud Function would be like: exports.simpleHttp = functions.https.onRequest((req, res) => { res.send({ msg: 'simpleHttp' }); }); This is a very simple example of Cloud Function, but you can adapt