Meteor-Community-Packages / raix-push

DEPRECATED: Push notifications for cordova (ios, android) browser (Chrome, Safari, Firefox)
https://atmospherejs.com/raix/push
MIT License
515 stars 197 forks source link

Mass removal of tokens in Meteor 1.7 #342

Open artpolikarpov opened 6 years ago

artpolikarpov commented 6 years ago

This is urgent. Just found that this piece of raix:push-update method:

      // xxx: Hack
      // Clean up mech making sure tokens are uniq - android sometimes generate
      // new tokens resulting in duplicates
      var removed = Push.appCollection.remove({
        $and: [
          { _id: { $ne: doc._id } },
          { token: doc.token },     // Match token
          { appName: doc.appName }, // Match appName
          { token: { $exists: true } }  // Make sure token exists
        ]
      });

...is deleting all tokens from _raix_push_app_tokens collection some times!

artpolikarpov commented 6 years ago

It happens when doc.token is undefined for some reason. I think we should change it to options.token.

da314pc commented 6 years ago

@artpolikarpov I think this method may be correct. When the message was sent were all the apps installed? If the app is not installed, I think the token is automatically removed on failed delivery, until the user opens the app and registers a new token.

artpolikarpov commented 6 years ago

@da314pc If you carefully read the source, then you see that on failed delivery, tokens are nulled, not removed.

da314pc commented 6 years ago

I'll do some digging. were all your tokens removed?

artpolikarpov commented 6 years ago

Not all but many. Thanks goodness I had a duplicate collection for them. In general, I warned.

CyberCyclone commented 6 years ago

I can confirm that this is an issue. As @artpolikarpov stated, the tokens are being being cleared. When this function comes around, null isn't considered in the $and statement and therefore is considered the same as: var removed = Push.appCollection.remove({ $and: [ { _id: { $ne: doc._id } }, { appName: doc.appName }, // Match appName { token: { $exists: true } } // Make sure token exists ] });

This therefore removes ALL tokens that are valid.

The workaround we have is:

if(doc.token){ var removed = Push.appCollection.remove({ $and: [ { _id: { $ne: doc._id } }, { token: doc.token }, // Match token { appName: doc.appName }, // Match appName { token: { $exists: true } } // Make sure token exists ] }); }