Firebase Cloud Messaging - How to validate Tokens? - android

I am using Firebase Cloud Messaging (FCM) and as per the abreviated code below everytime a new Token is generated on the Customer Device... I send this new TOKEN to my SERVER DB (Cloud) where I save it in order to be able to send future Push Notification from the Server to the Device using the CFM API.
//public class CFMInstanceIDService extends FirebaseInstanceIdService ...
public void onTokenRefresh() {
...
String cfmToken = FirebaseInstanceId.getInstance().getToken();
...
sendRegistrationToServer(customerGuid, cfmToken);
}
By doing this I have on the Server a list of ALL (multiples) Devices where a Customer is logged-in. (Tablet, Phone, iPhone, Android, etc)
Is there any way to verify/validate a Token at any time?
I would like to know/ensure that all the tokens that I have associated to a Customer belong to real Devices. I don't want to send Push Notifications to not-existing Tokens.

Here is an example curl request that shows how to validate a token without actually having to send a message:
curl -H "Content-Type: application/json" -H "Authorization: key=$FCM_API_KEY" https://fcm.googleapis.com/fcm/send -d '{"registration_ids":["$FCMTOKEN"]}'
Example invalid response:
{"multicast_id":7452350602151058088,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}
Example valid response:
{"multicast_id":9133870199216310277,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1502817580237626%f590ddc2f9fd7ecd"}]}
I got this answer from google's firebase support team.

Actually there is a workaround, you can use dry_run = true
This parameter, when set to true, allows developers to test a request without actually sending a message.
firebase docs
if user unsubscribe, you have a response with NotRegistered but real sending won't be performed

You can validate the FCM token by calling the
(GET) https://iid.googleapis.com/iid/info/YOUR_APP_TOKEN_HERE
[Header] => 'Authorization: key=YOUR_KEY'
Simple and easy.
If token is valid then it will return 200 status code with some more details in JSON format or if it's invalid then status code will be 400 with error detail in JSON format.

No such thing exists, the only information you can get from a token is app information and not wether it is valid or not
https://developers.google.com/instance-id/reference/server#get_information_about_app_instances
what you should be doing is watching for the response when you go to send push's out and if keys are not valid anymore the response will tell you what keys should be deleted withNotRegistered
https://firebase.google.com/docs/cloud-messaging/server

There is no way to validate if a token is still valid prior to send the downstream message. What you need to do is to check the response after sending the message and then check if the response contains any error.
For example, if the server returns an 200 + error:NotRegistered http code, it means that an existing registration token may cease to be valid.
In the section "Downstream message error response codes of FGC", you will find documented every possible status response.

Related

Huawei Push Kit "All the tokens are invalid"

After the push function is integrated, the server interface returns error code 80300007 when a push message is sent to some users. I am using a Mate 30 as a test device to obtain a token.
After the server sends a push request, the following response is returned:
{"_code": "80300007", "_msg": "All the tokens are invalid", "_requestId": "159496699937460153003301"}
In which situations user token will become invalid? This is because the server knows this only when invoking a push request. Can the client determine that if the token is invalid? What should the client do after the token expires?
Error code 80300007 means your token parameters are invalid according to the official guide. Please check your token parameter.
The message receipt capability can be accessed. If invalid tokens are found based on the receipt, push message will not sent to the tokens. For details, please check:
https://developer.huawei.com/consumer/en/doc/development/HMS-Guides/push-receipt

How to send push notification via postman using AWS Pinpoint

I want to send push notifications to mobile apps using REST API provided by AWS. I read their documentation but i am getting an error unauthorized. Does any one able to send push notification using REST API ?
The following is an example of a REST request int the documentation
GET /v1/apps/a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6/campaigns
Accept: application/json
Authorization: AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20161127/us-
east-1/mobiletargeting/aws4_request, SignedHeaders=accept;host;x-amz-date,
Signature=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a1b2c3d4e5f6
Host: pinpoint.us-east-1.amazonaws.com
X-Amz-Date: 20161127T202324Z
Following is the error I am getting
The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details
Currently, if I specify my AWS AccessKey & SecretKey in the Postman Environment as per the Amazon Pinpoint tutorial with POSTMAN I also get the same error message : The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details..
To get this setup working, I have specified my AWS AccessKey & SecretKey in Postman Authorization tab as illustrated below :
Below is a screenshot of the push notification message received on my Android phone:

FCM: Invalid registration token. Check the token format

I’m implementing Firebase Cloud Messaging (FCM) and am experiencing a problem that I’m unable to solve. I have implemented FirebaseMessagingService and FirebaseInstanceIdService according to the guide(s). When I go to Firebase Console for my app, and use the Notification function, I can successfully send a message to ALL my app instances (using the package name).
Now, in the code I have fetched the Firebase Instance Id (token) by use of the following code:
String token = FirebaseInstanceId.getInstance().getToken();
SendFirebaseTokenToServer(token);
(note that currently I’m using HTTP protocol, as my server does not yet have a cert). Anyway using the token I get from the call above, I go back to the Firebase Console and try to send a message to one (1) installed instance of my app. I grab the token from our server DB where it is stored as "varchar(max)". When I do that I get the following error message:
Invalid registration token. Check the token format.
I have googled that and found only one hit (having to do with Firebase and iOS):
http://stackoverflow.com/questions/41343520/ios-invalid-registration-token-check-the-token-format
That issue indicates that a cert was required (I think I’m reading it correctly). I’m not sure what I’m doing wrong. I need to get this to work using the Firebase Console first, then my server guy can start on his end knowing that it should work.
Turns out i was programatically encoding all POST or PUT parameters prior to sending to our server. the FCM token had a semicolon in it, which got encoded to a "%3A", seemingly causing the problem.
do NOT encode the FCM token.

Firebase Notifications - Invalid reg token, please check token format in Android

If I send push message by selecting a package from Firebase console, the push goes to all devices, but during sending to individual device, it displays the error:
Invalid reg token,please check token format
Error Snapshot:
UserID in console is not the registration token for Firebase messaging. By Firebase docs:
on initial startup of your app, the FCM SDK generates a registration token for the client app instance. If you want to target single devices or create device groups, you'll need to access this token by extending FirebaseInstanceIdService.
My last registration token looks like
cpeBAc1NkUE:APA91bEpAKHQTdgkWVdDzDZG8BPon0APaIhbbuSejDpZF-FO1gD2saDV7_EQDo2WEz0H6e5U-uf0i-v4b25NXgGzV2oUrNuboM5675WY7VCP3JcBl8BCNY7eV0VFGHT9oRox0EEoo_ch
In the other answer, you mentioned in the comments that you're Registration Token is:
cbuJIjkg9zQ%3AAPA91bHavuWCuRuWIBrDOoHUK-RsjU1yewigurrYzHe0cP‌​iTQINykKjrLf8E0qEwJj‌​3XmJ1IoTmn0r2EoLR_mA‌​HGOjlA61CnQ8aSn2WxWK‌​KByOwbsnqoVeaeWQIeGU‌​_yh4wnZ67soLtI
I noticed the % (percentage character) included in it, which isn't a usual character included in registration tokens. Figured that it was possible that this was encoded somehow. When decoded, this is the value:
cbuJIjkg9zQ:APA91bHavuWCuRuWIBrDOoHUK-RsjU1yewigurrYzHe0cP‌​iTQINykKjrLf8E0qEwJj‌​3XmJ1IoTmn0r2EoLR_mA‌​HGOjlA61CnQ8aSn2WxWK‌​KByOwbsnqoVeaeWQIeGU‌​_yh4wnZ67soLtI
Notice that the %3A was turned into : (colon). This is one of the usual characters. So I would suggest that you try the value above.
And as a reminder, the InvalidRegistration error (emphasis mine):
Check the format of the registration token you pass to the server. Make sure it matches the registration token the client app receives from registering with Firebase Notifications. Do not truncate or add additional characters.
Don't even encode it. Use it as is. Also, do note that the Registration Token should be kept secret.

How do I structure a notification key request to GCM Cloud Connection Server (XMPP)?

I would like to create a user notification key to group device notification by user. This topic is written about in the GCM documentation on User Notifications.
The GCM documentation claims to support notification key requests for both XMPP and HTTP connections, but does not give any examples regarding the structure of an XMPP message.
I am now attempting to request a notification key. I've used the information provided in the documentation and have structured my request message as such:
<message id="XK4EG-6"><gcm xmlns="google:mobile:data">{"operation":"create","notification_key_name":"appUser-Chris","registration_ids":["4","8","15"]}</gcm></message>
I receive the following error from GCM:
<message id="XK4EG-6" type="error" to="I REMOVED THIS"><gcm xmlns="google:mobile:data">{"operation":"create","notification_key_name":"appUser-Chris","registration_ids":["4","8","15"]}</gcm><error code="400" type="modify"><bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/><text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">InvalidJson: JSON_PARSING_ERROR : Missing Required Field: message_id</text></error></message>
I haven't been getting this sort of error with any of my previous messages to GCM, so I'm not sure how to handle it. It seems that I'm missing a message ID, but this is not required for notification key requests. Has anybody handled this?
I ran into a similar problem therefore I have been studying the issue for a few hours and here is the conclusion.
You are missing the "message_id": parameter in the JSON payload, it's a required parameter in CCS!:
message_id: In CCS, uniquely identifies a message in an XMPP connection. The value is a string that uniquely identifies the associated message. The value is a string. Required.
Note that in the GCM documentation on User Notifications topic "message_id": isn't included because use HTTP connection server.
Moreover, note that in XMPP "registration_ids": parameter doesn't exists in XMPP implementation, you should use "to": parameter instead and it only allow you to pass one registration id per message. In XMPP the value for "to": parameter is a string, not an array of strings:
to: In CCS, used in place of registration_ids to specify the recipient of a message. Its value must be a registration ID. The value is a string. Required.
Now, you should have something like this:
// This is code for a python xmpp server version
send_queue.append({"operation": "create",
"message_id": random_id(),
"to": REGISTRATION_ID,
"notification_key_name": "appUser-User1"})
But this only return me an ACK. I expect a notification_key but I receive only an ACK, I don't know why.
Server log:
sent message from server:
<message id="3"><gcm xmlns="google:mobile:data">{to: I REMOVED THE ID, operation: create, notification_key_name: appUser-User1, message_id: 5xEYEIHZ}</gcm></message>
got message:
<message><data:gcm xmlns:data="google:mobile:data">"message_id":"5xEYEIHZ","message_type":"ack","from":"I REMOVED THE ID"}</data:gcm></message>
This is an ACK but not the register_key expected :(
Conclusion
I think that obtain a notification key from XMPP server is not possible for now. Documentacion is not available and the methods that I tried returns an ACK but not the notification key.
For now, we only can use the HTTP method, which works fine, I do a test from a linux console:
curl --header "Authorization: key=YOUR_KEY" --header "Content-Type: application/json" --header "project_id:YOUR_PROJECT_ID" https://android.googleapis.com/gcm/send -d "{\"operation\":\"create\",\"notification_key_name\":\"appUser-User\",\"registration_ids\":[\"YOUR_REGISTRATION_ID\"]}"
output:
{"multicast_id":7151337537866826426,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1406728451796338%921c249af9fd7ecd"}]}

Categories

Resources