FCM and Typescript Async Await: Network Timing Out

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 :)

+5
source share
2 answers

Most likely, there is some function that you call on firebase api, which should be await ed, but it is not. I am not familiar with firebase to tell you which one, but it looks like any call to the Firebase API is potentially await .

Here you must make sure that you have the type definitions installed for firebase and use a good editor. Take a look at all your firebase calls and make sure that none of them secretly return a promise.

In addition, you must make sure that all your functions and variables are as strict as possible, as this will help you avoid any problems.

So, the following lines look suspicious to me:

 fs.doc(`member/${memberID}`); transaction.update(docRef, {badgeCount: ++count}); const doc = admin.firestore().doc(`member/${memberID}`); 
0
source

This is because you open too many http connections to send push notifications, ideally you should create a package of 5.10 .. to send push.

Try changing

 return await Promise.all(ids.map(async (id) => { ... }); 

in

 while(ids.length) { var batch = ids.splice(0, ids.length >= 5 ? 5 : ids.length); await Promise.all(batch.map( async (id) => { ... }); } 
0
source

Source: https://habr.com/ru/post/1273561/


All Articles