I am new to Typescript and I am trying to use the async function and wait. From time to time I get fcm network timeouts, and I believe that this is due to the incorrect return of my promises.
Here is my cloud function for sending push notifications. Two functions that use the wait keyword are incrementBadgeCount and sendPushNotification :
export const pushNotification = functions.firestore .document('company/{companyId}/message/{messageId}/chat/{chatId}') .onCreate(async event => { const message = event.data.data(); const recipients = event.data.data().read; const messageId = event.params.messageId; const ids = []; for (const key of Object.keys(recipients)) { const val = recipients[key]; if (val === false) { ids.push(key); } } return await Promise.all(ids.map(async (id) => { const memberPayload = await incrementBadgeCount(id); const memberBadgeNumberString = memberPayload.getBadgeCount().toString(); const senderName = message.sender.name; const senderId = message.sender.id; const senderMemberName = message.senderMember.name; const toId = message.receiver.id; const text = message.text; const photoURL = message.photoURL; const videoURL = message.videoURL; const dealId = message.dealId; const dealName = message.dealName; const payload = { notification: { title: `${senderName}`, click_action: 'exchange.booth.message', sound: 'default', badge: memberBadgeNumberString }, data: { senderId, toId, messageId } }; const options = { contentAvailable: true } ........ const deviceIDs = memberPayload.getDeviceID() return await sendPushNotification(id, deviceIDs, payload, options); })); });
Here is the incrementBadgeCount function, which increases the number of icons for the payload and returns some information for the payload:
async function incrementBadgeCount(memberID: string): Promise<MemberPushNotificaitonInfo> { const fs = admin.firestore(); const trans = await fs.runTransaction(async transaction => { const docRef = fs.doc(`member/${memberID}`); return transaction.get(docRef).then(doc => { let count: number = doc.get('badgeCount') || 0; const ids: Object = doc.get('deviceToken'); transaction.update(docRef, {badgeCount: ++count}); const memberPayload = new MemberPushNotificaitonInfo(count, ids); return Promise.resolve(memberPayload); }); }); return trans }
And finally, the sendPushNotification function, which interacts with FCM and discards the payload and clears bad device tokens:
async function sendPushNotification(memberID: string, deviceIDs: string[], payload: any, options: any) { if (typeof deviceIDs === 'undefined') { console.log("member does not have deviceToken"); return Promise.resolve(); } const response = await admin.messaging().sendToDevice(deviceIDs, payload, options); const tokensToRemove = []; response.results.forEach((result, index) => { const error = result.error; const success = result.messageId; if (success) { console.log("success messageID:", success); return } if (error) { const failureDeviceID = deviceIDs[index]; console.error(`error with ID: ${failureDeviceID}`, error); if (error.code === 'messaging/invalid-registration-token' || error.code === 'messaging/registration-token-not-registered') { const doc = admin.firestore().doc(`member/${memberID}`); tokensToRemove.push(doc.update({ deviceToken: { failureDeviceID: FieldValue.delete() } })); } } }); return Promise.all(tokensToRemove); }
I would appreciate help in pulling this Typescript up :)