i am trying to send push notification like below:
const { getFirestore } = require('firebase-admin/firestore');
const { initializeApp } = require('firebase-admin/app');
const { https } = require('firebase-functions/v2')
import { getMessaging } from "firebase-admin/messaging";
const { onRequest } = require("firebase-functions/v2/https");
const { onCall, HttpsError } = require("firebase-functions/v2/https"
initializeApp();
const db = getFirestore();
const messaging = getMessaging();
const auth = getAuth();
exports.missingDataProgress = onSchedule("every 24 hours", async (event:any) => {
logger.log("Start of missingDataProgress")
const dashboardReadyRef = new FieldPath("profile", "dashboardReady")
const appColRef = db.collection("users"); // best practice to use "ColRef" instead of just "Ref"
const querySnapshot = await appColRef.where(dashboardReadyRef, '==', false).get()//
querySnapshot.forEach(async(doc:any) => {
let data:any
data = doc.data()
//logger.log("v2:found trial and active data as:", data)
if(data.profile !== undefined && data.profile.pushToken !== undefined && data.profile.pushToken !== '' && data.profile.pushToken !== null){
const pushPayload = {
title: "Missing Data!",
body: genMissingDataMessage(),
image: "",
}
logger.info("push payload is", pushPayload)
const message:any = {
token: data.profile.pushToken,
notification: pushPayload,
}
try{
await messaging.send(message);
logger.info("push message sent")
}catch(err:any){
logger.error("failed to send push token", err)
if(err.code === 'messaging/invalid-registration-token' || err.code === 'messaging/registration-token-not-registered'){
logger.error("detected no longer valid token so removing it")
data.profile.pushToken = ''
const nwColRef = db.collection("users")
await nwColRef.doc(data.profile.uid).update({"profile": data.profile})
}
}
}
});
})
You're not dealing with promises correctly for Cloud Functions. Your function must return a promise that resolves only after all other async work is complete. When you use forEach, that "ignores" all of the promises within the lambda you pass to it, and your function returns without waiting for completion, which can cause problems for the abandoned async work.
See also:
The error you have is the same error discussed in this other questions, which also were dealing with promises incorrectly:
Firebase Functions: Client network socket disconnected error for push notification sent via FCM
Firebase Cloud Function - How can I solve this error: ECONNRESET
Consider converting to a for/of loop instead of forEach, or use Promise.all
to create a new promises that resolves only after the provided list of promises resolve. This has been discussed in detail in other questions: