ToothlessGear / node-gcm

A NodeJS wrapper library port to send data to Android devices via Google Cloud Messaging
https://github.com/ToothlessGear/node-gcm
Other
1.3k stars 206 forks source link

Failing push notification #246

Closed ColdLogical closed 8 years ago

ColdLogical commented 8 years ago

Perhaps I am doing something wrong, as I am having a huge problem finding anything that describes the process end to end.

I am generating a registration id in an iOS application with

FIRInstanceID.instanceID().token()

I push this up and on my server get it to create a notification key for the user

function createNotificationKeyWithTokenForPlayer(token, playerID) {
    var notificationKeyName = "hm-ttt-user-" + playerID;
    var payload = {
        "operation": "create",
        "notification_key_name": notificationKeyName,
        "registration_ids": [ token ],
    };

    var options = {
        url: 'https://android.googleapis.com/gcm/notification',
        port: app.get('port'),
        method: 'POST',
        headers: {
            "Authorization":  "key=#ServerKeyFromFirebaseCloudMessaging#",
            "Content-Type": "application/json",
            "project_id": "#SenderIDFromFirebaseCloudMessaging#",
        },
        json: payload,
    }

    request(options, function(error, response, body){
        if(error) {
            console.log("Failed creating notification key with ", token, " for player ", playerID);
        }

        if(body) {
            var notificationKey = body["notification_key"];
            if (typeof notificationKey == "string") {
                console.log("Succeeded creating notification_key_name ", notificationKeyName, " and adding token to ", body["notification_key"]);

                removeTokenForPlayerIdFromNewTokens(token, playerID);

                setNotificationKeyForPlayer(body["notification_key"], playerID);
            } else {
                console.log("Failed creating notification_key and adding token to notification key: ", body);
            }
        }
    });
}

After that, I try sending a push notification with

function sendPushNotification(notificationKey, title, message) {
    var sender = new fcm.Sender('#ServerKeyFromFirebaseCloudMessaging#');
    var regTokens = [ notificationKey ];

    var message = new fcm.Message();

    message.addNotification({
        title: title,
        body: message,
    });

    sender.send(message, { registrationTokens: regTokens }, function (err, response) {
        if(err) console.error(err);
        else    console.log(response);
    });
}

The response i get is:

{ multicast_id: 7209199615699496000,
  success: 0,
  failure: 1,
  canonical_ids: 0,
  results: [ { error: 'NotRegistered' } ] }

If i use the registration id directly instead of the notification key

{ multicast_id: 9089391759336166000,
  success: 0,
  failure: 1,
  canonical_ids: 0,
  results: [ { error: 'InternalServerError' } ] }

Can someone maybe point me to the flaw? I cannot seem to find good documentation to find it myself.

hypesystem commented 8 years ago

When sending to a notification key, you shouldn't be using the registrationTokens field. You should use this instead (as per the Recipients section of the README):

sender.send(message, { notificationKey: notificationKey }, function (err, response) {
    if(err) console.error(err);
    else    console.log(response);
});

This should solve the first case!

How exactly does your code look when you are sending to the registration token directly? I don't understand why that results in an InternalServerError :smile:

govardhanaraoganji commented 8 years ago

As hypesystem said is right and if you get response result as 'NotRegistered' i.e) user unregistered the app ( Un installed the app) from device.

Please follow the steps properly, which mentioned on doc.

ColdLogical commented 8 years ago

@govardhanraoganji except I am the user and I haven't uninstalled the app...

govardhanaraoganji commented 8 years ago

@ColdLogical please check once again you are passing correct device_id or not otherwise wise you won't get response as NotRegistered.

ColdLogical commented 8 years ago

@govardhanraoganji In an iOS application, the only documentation I have found to generate the registration id is the FIRInstanceID.instanceID().token(). Is there some more clear documentation you can point me to somewhere?

govardhanaraoganji commented 8 years ago

@ColdLogical If you won't get notification only for IOS, use 'node-apn' module to send notifications to IOS devices.

If you use 'node-apn' to send notifications to IOS device, IOS Dev no need to handle any code, notification will come directly.

Otherwise, IOS Dev should handle the logic, Here is the link. https://developers.google.com/cloud-messaging/ios/start

ColdLogical commented 8 years ago

@hypesystem Changing the call to notificationKey worked! Thank you so much.

Since notificationKey is deprecated, do I instead use the to?

hypesystem commented 8 years ago

@ColdLogical Great! Yeah, to is probably what you should use :smile:

govardhanaraoganji commented 8 years ago

@ColdLogical great yar!, if you want to send notifications to multiple devices use below code otherwise to sufficient.

var regTokens = []; // list of device_id's
sender.send(message, { registrationTokens: regTokens }, function (err, response) {
    if(err) console.error(err);
    else    console.log(response);
});

Request format: https://developers.google.com/cloud-messaging/http-server-ref#send-downstream