question

clare0526 avatar image
clare0526 asked

Keep receiving "InvalidRegistrationId" when sending a message

Hi everybody, I just tried my first time to send a message to my app in kindle emulator, but as title, never success so far. Here are all I have done: 1. Add a new app "ADMMessenger" in developer.amazon.com. 2. Add a security profile and generate API key with package name and MD5 signature of my app. 3. Associate the profile with "ADMMessenger" and turn "Device Messaging" ON. 4. Add API key to \assets\ api_key.txt in my app project. 5. Sign and install my app into kindle emulator and run. 6. Successfully registered and get the "Registration ID". 7. Successfully acquired "Access Token" with "Client ID" and "Client Secret" of the security profile. However, when I try to post a message with the "Access Token" and "Registration ID", it always return me "InvalidRegistrationId". I'm pretty sure the token hasn't expired yet, and the API key and client ID/Secret are belongs to the same profile.
amazon device messaging
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

ethertree avatar image
ethertree answered
I don't know if this helps but there were two situations where I got the InvalidRegistrationId: 1. When the device had the app uninstalled 2. When I used a key in assets/ api_key.txt which did not come from the Security Profile associated with the app. This applies where it's from a separate Security Profile or from a completely different source which in my case word for "Login with Amazon". Did you try sending a message while the app was running? I only tried on a real device not the emulator, but presumably the actual instance where you registered with ADM must still be running for the regId to be valid?. I just wonder if shutting down and starting a fresh instance has somehow unregistered the device from ADM. Presumably you also have registered the emulated instance with an Amazon account? I had a SERVICE_NOT_AVAILABLE fail at registration on my device in this circumstance, so probably not your problem, but worth checking.
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

clare0526 avatar image
clare0526 answered
Hi ethertree, thanks for your reply. But... 1. I always send messages when app is on since I want to see if it can receive or not. 2. I've suffered the same problems too, but solved by registering the device just as you said, so it shouldn't be a problem anymore. Actually the sample code I used is exactly the one which come along with downloaded ADM library, so it shouldn't be app's problem, either. I'm wondering is there anything I missed to connect "Registration ID" with "sender"? I'm asking because of following sentence: "ADM may return InvalidRegistrationId if the Registration ID has expired due to lack of user activity, or if the Registration ID does not correspond to the sender identified by the provided access token." in https://developer.amazon.com/sdk/adm/sending-message.html
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

ethertree avatar image
ethertree answered
It won't be a registrationId timeout. Although I don't know the length of time but I assume they are talking about weeks at least for that situation to occur. It's meant to be stored on the server. And I've seen it remain valid for days at least. Matching up the registrationId to the sender really means the client id/secret used on the server (the sender) comes from the same Security Profile as the key used for signing the app which asks for the registrationId. It's just saying use the credentials from the same security profile everywhere. It's pretty baffling. If you have copied the registrationId to your server and fired a message to that Id from that server I don't know what is could be. I'd suggest a couple more checks which you have probably tried already: - Have you tried it on emulated instanced of all the suitable Kindle Fires? And get the same result? Do you have access to a real Kindle just to check it's not an emulator issue? - Debug to the point where you get the registrationId, and then copy the regId from the debugger and pasted into a test to fire a message? That would at least rule out any mangling of the regId anywhere. Otherwise, I'm pretty much out of ideas. Hope Amazon support can help! Tree
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

clare0526 avatar image
clare0526 answered
Ha, you are right, I need a real device for testing, I'll pass your word to my boss:) But I still doubt that it's device's problem since the message is block by ADM server. I'm also sure the regID is equal to what onRegistered() got, since I've tried to modify one character of it and the return turns to"retryAfter": null.
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Sujoy@Amazon avatar image
Sujoy@Amazon answered
Hi Clare0526, ADM is supported on Kindle Fire HD 8.9" 4G, Kindle Fire HD 8.9", Kindle Fire HD 7", and Kindle Fire (2nd Generation) devices and the equivalent emulators as well. Have you registered your emulator with an Amazon account?
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Sujoy@Amazon avatar image
Sujoy@Amazon answered
Ok. I found the reason to get the reason of "InvalidRegistrationId" sever error code. You would get it in the following scenario. Lets say you have 2 security profiles (sp1 and sp2) in your account in developer portal. Now you add an api key in sp1 by registering the package name and MD5 hash of the certificate you use to sign your adm integrated app. Now by using this api key (by placing it the assets/ api_key.txt file) you would receive the device registration id for your app from ADM sdk in your app client. In server side you are supposed to receive an access token by using clientId and clientSecret what are associated with a security profile. Now if you use clientId and clientSecret of sp2 (the one you did not add the api key for client) to receive the access token and with this token if you send a message to the registration id you achieved in the above way, you would get "InvalidRegistrationId" back from ADM server. So you should use a same security profile to generate the api key in client and to get the access token in server. I can see 5 security profiles you have created in your account. Can you please make sure you are using only one of them in your system? Please post back the result. Thanks.
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

clare0526 avatar image
clare0526 answered
Hi, thanks for the answer. I did have two profiles when I posted this issue, but I was pretty sure the API key, client ID and client secret that I used are all refer to the first one. (although I applied 3 API keys at that profile and only use the second one, I'm not sure if that's the cause or not). Anyway, I workaround this issue by creating a new emulator(8.9"HD, same as before), renaming my package (to get different API key) and redoing the whole process, several times (that's why you saw 5 profiles there), and finally my app receive the first message. By the way: 1. Do we have any way to remove unused API keys or apps? 2. When I send multiple messages in a row, only the last one can be received, is that correct behavior?
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Bipin@Amazon avatar image
Bipin@Amazon answered
To ensure high availability, ADM limits the number of messages that can be sent over a given period of time. ADM makes no guarantees about delivery or the order of messages. Due to varying network conditions, messages may be delivered more than once. Your app must be able to handle instances of duplicate messages. Messages expire. The default expiration time is one week; the maximum is one month. You can also set a custom expiration time for a message when you send it. When a message expires, ADM may remove the message from the delivery queue. We don't remove the security profile or API key as this is used for tracking purpose. No access from developer portal. If it has to be removed from the developer profile, you have to raise the contact us( https://developer.amazon.com/help/contactus.html) with details.
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

marko-psy84 avatar image
marko-psy84 answered
Hi, i have the same problem as describe below. I pretty sure I have the right credentials and secret_ID associated with the package, but i keep receiving "InvalidRegistrationId". I m trying to send with PHP, i used the sample code found here: https://forums.developer.amazon.com/forums/thread.jspa?threadID=1537&tstart=15 I have the acessToken, i can registered with the device, but when i comes to send the message, always the same answer. I using tomcat for retrieve the acessToken, everything works. My code: function sendEventToKindleDevices(){ $accessTokenUrl = 'http://localhost:8080/ADMAdmin/ADMAdmin?action=getAuthToken'; $accessToken = file_get_contents($accessTokenUrl); $payload = array(); $headers = array('Accept: application/json', 'Content-Type: application/json', 'X-amzn-type-version: com.amazon.device.messaging.ADMMessage@1.0', 'X-amzn-accept-type: com.amazon.device.messaging.ADMSendResult@1.0', 'Authorization: Bearer '.$accessToken); $ch = curl_init(); $regId = "amzn1.adm-..."; $url = " http://api.amazon.com/messaging/registrations/".$regId."/messages"; $data = array("msgType" => "new_fav_event", "channel" => "nnn"); $payload['data'] = $data; $payloadString = json_encode($payload); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $payloadString); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch,CURLOPT_HTTPHEADER,$headers); $result = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); echo("HttpCode response: ".$httpCode." Response: ".print_r($result, true)." RegId = ".$regId."\n"); curl_close($ch); } Thank you
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Sujoy@Amazon avatar image
Sujoy@Amazon answered
Hi Marko, Can you please echo $accessToken before sending the message? I would like to just make sure that you are getting a valid access token back from ADMAdmin service running on tomcat. Why do you getting access token by using java server and using php for sending message? Why cant you accomplish both the actions in a PHP script? It seems to be quite unnatural running two web servers in localhost for doing similar tasks. If you want to have your app back end to be running on PHP, you should curl the ADM server to get the access token also. I am sure this is not the reason of the InvalidRegistrationId but it is complicating to debug the issue on your own. Please make sure that the security profile you have used to generate an API key (the one you placed in res/ api_key.txt) for your app client, you should use the clientId and clientSecret of the same profile in getAccessToken action in your app server while fetching the access token from ADM server. InvalidRegistrationId might be encountered in the following scenario. - In your android app client you have kept one api key (associated with a security profile) in asset and achieved the registrationId from ADM sdk. - In the back end while performing a HTTP request to ADM server to get an access token by using clientId and clientSecret of different security profile.
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.