Skip to content
This repository has been archived by the owner on Dec 1, 2022. It is now read-only.

iOS: Uninstall and reinstall app causes duplicate push messages #101

Closed
CeccoCQ opened this issue Sep 18, 2015 · 11 comments
Closed

iOS: Uninstall and reinstall app causes duplicate push messages #101

CeccoCQ opened this issue Sep 18, 2015 · 11 comments
Assignees

Comments

@CeccoCQ
Copy link

CeccoCQ commented Sep 18, 2015

This is my code:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
...........

    _registrationKey = @"onRegistrationCompleted";
    _messageKey = @"onMessageReceived";

    NSError* configureError;
    [[GGLContext sharedInstance] configureWithError:&configureError];
    NSAssert(!configureError, @"Error configuring Google services: %@", configureError);

    _gcmSenderID = [[[GGLContext sharedInstance] configuration] gcmSenderID];

    if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) {
        UIRemoteNotificationType allNotificationTypes = (UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge);
        [application registerForRemoteNotificationTypes:allNotificationTypes];
    }
    else {
        UIUserNotificationType allNotificationTypes =(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
        UIUserNotificationSettings *settings =[UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    }

    GCMConfig *gcmConfig = [GCMConfig defaultConfig];
    gcmConfig.receiverDelegate = self;
    [[GCMService sharedInstance] startWithConfig:gcmConfig];

    __weak typeof(self) weakSelf = self;
    _registrationHandler = ^(NSString *registrationToken, NSError *error){
        if (registrationToken != nil) {

            weakSelf.registrationToken = registrationToken;            
            [weakSelf subscribeToTopic];

            NSDictionary *userInfo = @{@"registrationToken":registrationToken};
            [[NSNotificationCenter defaultCenter] postNotificationName:weakSelf.registrationKey object:nil userInfo:userInfo];

        }
        else {
            DDLogInfo(@"Registration to GCM failed with error: %@", error.localizedDescription);
            NSDictionary *userInfo = @{@"error":error.localizedDescription};
            [[NSNotificationCenter defaultCenter] postNotificationName:weakSelf.registrationKey object:nil userInfo:userInfo];
        }
    };

.........
}


- (void)applicationDidBecomeActive:(UIApplication *)application {
    [[GCMService sharedInstance] connectWithHandler:^(NSError *error) {
        if (error) {
            DDLogInfo(@"Could not connect to GCM: %@", error.localizedDescription);
        }
        else {
            _connectedToGCM = true;
            [self subscribeToTopic];
        }
    }];
}


- (void)subscribeToTopic {
       if (_registrationToken && _connectedToGCM) {
        [[GCMPubSub sharedInstance] subscribeWithToken:_registrationToken topic:SubscriptionTopic options:nil handler:^(NSError *error) {
            if (error) {
                if (error.code == 3001) {
                    DDLogInfo(@"Already subscribed to %@", SubscriptionTopic);
                }
                else {
                    DDLogInfo(@"Subscription failed: %@",error.localizedDescription);
                }
            }
            else {
                self.subscribedToTopic = true;
            }
        }];
    }
}


- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {

    GGLInstanceIDConfig *instanceIDConfig = [GGLInstanceIDConfig defaultConfig];
    instanceIDConfig.delegate = self;
    [[GGLInstanceID sharedInstance] startWithConfig:instanceIDConfig];

        [[GGLInstanceID sharedInstance] deleteIDWithHandler:^(NSError *error) {
            [[GGLInstanceID sharedInstance] deleteTokenWithAuthorizedEntity:_gcmSenderID scope:kGGLInstanceIDScopeGCM handler:^(NSError *error) {
                if(error) {
                    DDLogError(@"%@", error.description);
                }
                else {
                    [FsPrefsUtils setTokenDeleted:[NSNumber numberWithBool:YES]];
                    _registrationOptions = @{kGGLInstanceIDRegisterAPNSOption:deviceToken, kGGLInstanceIDAPNSServerTypeSandboxOption:@YES};
                    [[GGLInstanceID sharedInstance] tokenWithAuthorizedEntity:_gcmSenderID scope:kGGLInstanceIDScopeGCM options:_registrationOptions handler:_registrationHandler];
                }
            }];
        }];
}

I've tried with deleteIDWithHandler and deleteTokenWithAuthorizedEntity but without success.
I always receive duplicates messages.

This is the message that I send:

{
    "to": "/topics/global",
    "notification": {
        "title": "notification_title3",    
        "body": "notification_body3",
        "sound": "default"
    },
    "data": {
        "uid": 72699,
        "persist": true,
        "type": 1,
        "payload": {
            "title": "data_title",
            "body": "data_body"
        },
    },
    "priority":10
}

How can I solve?

@silvolu
Copy link
Contributor

silvolu commented Sep 19, 2015

@CeccoCQ thanks for reporting. I can currently reproduce even without uninstall/reinstall and I'm investigating what is going on. I will update this issue when I know more.

@dral3x
Copy link

dral3x commented Sep 21, 2015

👍 on this. Also another 👍 for all of us because we're all Italians :)

@CeccoCQ
Copy link
Author

CeccoCQ commented Sep 24, 2015

Any news about this issue?

@silvolu
Copy link
Contributor

silvolu commented Sep 24, 2015

We have identified the issue and we are working on a fix, I'll update this thread as soon as it becomes available.

@vigneswara
Copy link

Any update on this? Still facing this problem

@mehmoodbahria
Copy link

@silvolu sir when will you update it?? I am getting same issue..Kindly help me

@mohitsharma0690
Copy link

@mehmoodbahria what version of GCM library are you guys using?

@mehmoodbahria
Copy link

@mohitsharma0690 i am using pod to configure gcm

@mehmoodbahria
Copy link

@mohitsharma0690 i am using 7.3.1 version..waiting for your response.

@joshfriend
Copy link

Having worked through my share of duplicate push notification issues, I have a theory:

The GCM token that the app gets probably changes between installs. It can also change periodically even if the app is not reinstalled.

The official documentation for GCM says:

If you try to send a message using an old registration token, GCM will process the request as usual, but it will include the canonical ID in the registration_id field of the response. Make sure to replace the registration token stored in your server with this canonical ID, as eventually the old registration token will stop working.

This means that even though the GCM token changed, the old one still works. If you don't also send the old device token to your server when you get a new one, chances are good that you will accidentally send a push to both IDs, creating duplicate push messages. Since this is a fresh install, I'm not sure how you are supposed to know what the old ID was, especially since you can't de-register it when the app is being uninstalled.

When using the APNS service directly, the old token becomes invalid if a new one is assigned and won't receive any push messages. You are notified one time through the feedback service that the token is no longer valid.

Ideally, GCM would de-duplicate pushes sent to both the old token and the updated canonical id, but this would be difficult to do, especially if the two tokens were not contained in the same multicast push message.

@mohitsharma0690
Copy link

@joshfriend you're somewhat correct. This was the expected behaviour before but we've made changes on our end and you shouldn't see duplicate messages no more (well no more for new registrations, existing registrations which haven't been invalidated would still lead to dupes).

Some details, GCM on iOS now maps the APNS token to a unique GCM registration token so if APNS's feedback service tells us that some token is no longer valid the unique GCM registration token associated with it will also be invalidated (as before). But now in the case of app uninstall and re-install if you get back the same APNS token you will get back the old GCM registration token if it can be updated and if not then you will get back a new GCM token along with invalidating the old GCM token.

So there shouldn't be any dupes anymore :)

I'm going to mark this as closed if you guys see duplicate messages on app uninstall and resinstall (with new tokens) please let us know.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants