Reputation: 593
I am having trouble writing a scheduled function to read data from firestore. The function is successfully running every 1 minute but now the problem is reading the data from firestore. I am using async-await because I want to loop through the data after the read then do then so some update. Kindly help I am using firebase functions for the first time. Below is my function. I keep getting this error cannot read property map of undefined
exports.checkDefaultedPledges = functions.pubsub.schedule("every 1 minutes").onRun( async
(context) => {
console.log("This will be run every 2 minutes!");
const time = new Date().getTime();
const snapshot = db.collection("pledges").get();
const res = await snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
console.log(res);
return null;
});
Is it possible for me to write this function without using the .then()?
Upvotes: 0
Views: 905
Reputation: 83058
The problem I am having is that no data is being returned when reading the data.
You need to use await
when calling get()
, since it is an asynchronous method.
On the other hand, you should not use await
in const res = await snapshot.docs.map()
since docs
is a simple property (no asynchronicity here).
If you want to update all the docs in the pledges
collection, you can use a batched write as follows:
exports.checkDefaultedPledges = functions.pubsub.schedule("every 1 minutes").onRun(async (context) => {
const time = new Date().getTime();
const snapshot = await db.collection("pledges").get();
const batch = db.batch();
snapshot.forEach(doc => {
batch.update(doc.ref, { "updateTime": time });
})
return batch.commit();
});
Note that a batched write can contain up to 500 operations: so if you know your collection has/will have more than 500 docs, you should use Promise.all()
as follows:
exports.checkDefaultedPledges = functions.pubsub.schedule("every 1 minutes").onRun(async (context) => {
const time = new Date().getTime();
const snapshot = await db.collection("pledges").get();
const promisesArray = snapshot.docs.map(doc => doc.ref.update({ "updateTime": time }));
return Promise.all(promisesArray);
});
Side note:
It is a best practice to use FieldValue.serverTimestamp()
instead of using the JS Date()
, especially when you are writing to Firestore from a client app. serverTimestamp
"returns a sentinel used with set()
or update()
to include a server-generated timestamp in the written data".
Since a Cloud Function is executed by a server, it is not a must, but you could adapt your code as follows:
const time = admin.firestore.FieldValue.serverTimestamp();
Upvotes: 1