简体   繁体   中英

Performing update operations on Meteor.users collection within catching a rejected promise (using fcm-push+Meteor)

I am utilizing an NPM package called fcm-push ( https://www.npmjs.com/package/fcm-push ) in order to send FCM notifications to various mobile devices based on a generated message. There's no issue when the FCM message successfully sends, however if the FCM message sending fails because the FCM token associated with the message is "NotRegistered," then I would like to remove the FCM token associated with the user.

However, whenever the FCM message fails to send, the token never gets removed from the user's profile, even though it triggers the call back on calling Meteor.users.update . If there is any way for me to modify the database operation so I can successfully perform the update operation on the profile, some guidance would be appreciated.

[INFO] -- 10:59:23 | "Error" | Data: {
  "data": "NotRegistered",
  "haltDate": "2017-03-31T10:59:23.660Z"
}  | User: cHkDSqQBMVc:APA91bFXCwp1-nxi2xxVEZARAMHs48kLm6FN0tbgmjv1lP1-LsBty_6gCFqGqDxGV9JrpCDG9pVFIxUz-77-6QxbIMa2OWmG4xoN2-E_8UoD_xe8MVoDb-DZY_KSZcMh4Bg_5F18ltg0

    return fcm.send(fcmMessage).then((data) => {
        var processEndDate = new Date();
        console.log("Response Data "+data+" ------ "+startDate+" --> "+processEndDate);
        loggerA.info("Response", {data: data, startDate: startDate, endDate: processEndDate}, token);
        return {
            method: 'SendMessage',
            status: JobberServer.Status.SUCCESS,
            dateEnd: processEndDate,
            response: data
        };
    }).catch((err) => {
        loggerA.info("Error", {data: err, haltDate: startDate}, token);
        Meteor.users.update({_id: targetId}, {$pull: {"profile.fcmTokens": {id: token}}}, {multi: true}, function (err, docsModified) {
            loggerA.info("Deregister Op", {token: token, res: err, noOfDereggedTokens: docsModified}, "NAN");
        });
        return {
            method: 'SendMessage',
            status: JobberServer.Status.FAIL,
            dateEnd: null,
            response: err
        }
    });

Ended up fixing it myself - simply just had to remove the update operation from the method itself, wrap the promise using Promise.await(...) and then return the return value of that so it can be consumed by the Meteor.call(...) callback. The resulting code in the method looks like this:

    return Promise.await(fcm.send(fcmMessage).then((data) => {
        var processEndDate = new Date();
        console.log("Response Data "+data+" ------ "+startDate+" --> "+processEndDate);
        loggerA.info("Response", {data: data, startDate: startDate, endDate: processEndDate}, token);
        return {
            status: JobberServer.Status.SUCCESS,
            response: data
        };
    }).catch((err) => {
        loggerA.info("Error", {data: err, haltDate: startDate}, token);
        return {
            status: JobberServer.Status.FAIL,
            response: err
        };
    }));

This allows me to get status and response from the response parameter of the method's call back since await waits for the promise to resolve first before returning the value. Afterwards, I can perform the necessary operations without any issue based on the response.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM