I have a Xamarin Forms application where we're using Azure Notification Hub to send messages to both Android and iOS devices.
Whenever someone logs into the application a record is created (or updated) for that device. Various information about that device is stored: who it belongs to, installation id, token, etc.
We then call the hub method CreateOrUpdateInstallationAsync() for that device's installation. In the case of a new install or cleared data we will be passing in a new installation to Azure Notification Hub to create the installation. In the case of an existing installation we're simply updating the tags so that the correct user will be notified when a message is sent.
This all seems to work as expected. After the call to CreateOrUpdateInstallationAsync() we will see both a Native and a Template registration in the hub for a given installation id. I can log in and out of the application and those device records are updated in the hub. I can see the tags change.
However, for some reason, some Android devices will stop receiving notifications. Sometimes this is immediate. That is, right after the app is installed and the device is registered with the hub, it can't receive messages. Other times it could take up to 24 hours or so, but a device that was receiving messages will suddenly stop.
If I use the Azure Portal to try and directly send a message to the broken Android device it tells me that there are "no matching targets". If I use the Firebase console to send a message to the broken device the message is never received.
iOS never seems to have an issue.
I'm unsure how to proceed. It's almost as if the FCM token is invalid at some point. From what I've read the only time it really should become invalid is if the app is newly installed, the data was cleared, or the device was restored. But this invalidated token seems to happen immediately after install or after a day or so of previously receiving notifications without issue.
If this is the case, is there some way I'm supposed to be aware of this when sending a template message through the hub?
Related
It looks like the Android Firebase stops syncing until I re-login.
I push data to Firebase using the Firebase Admin SDK.
I send an FCM message to the phone to wake it up. The message contains the new data's push ID. The Android app reads Firebase until it sees the new push ID and then processes the data.
Normally this works. Occasionally the phone gets in a state where it doesn't see the new push ID. Logging out/in causes it to start working again.
This is not a race condition because I send the push ID to the phone in the FCM message. That lets the Android app read until it sees the push ID (or time out sometimes in my case). I have verified that the data was pushed into Firebase and that the Android app is attempting to read the right ID.
Once the phone is in this state it continues to fail until I re-login. There are no errors or exceptions (the uid is not null, I can attach listeners). It just never sees the new push ID. If I log out and log back in (without restarting the app) then it starts working again. This is a very very intermittent problem.
A work around would be for me to store the credentials and re-login with a new auth token when the phone fails to read a known good push ID (btw, the app uses custom tokens generated by the Firebase Admin SDK)
Question: Am I missing something regarding authentication? Why does the Android app stop syncing until I re-login?
I am trying to implement push notifications in Unity Android, I've completed the Quick Start and have done everything I can find out to do, but when I try to do a test push using the "Test" button on the Quick Start page, I get the message "Can't find any registered devices yet...". No errors or messages appear in the Parse logs, just this on the Quick Start page itself just below the "Test" button.
I have installations in the "Installation" table. I've even added code to my app to subscribe to channels (I've tried various names, as well as an empty string ""), and these subscriptions appear in the Installation table for those installation records.
When I go to initiate a push from the Push page on the dashboard, it correctly lists the number of devices that will be targeted by the push, but none of my devices receive anything, and it shows that 0 pushes were sent. And I keep receiving the "Can't find any registered devices yet..." message on the Quick Start page.
I even tried building the Push sample app, found some things wrong with it which prevented it from even running on the device, but I cannot get it to even register an installation, much less receive a push notification.
I have been working on this for over a week now, and I'm desperate for some help. I really need to know the reasons why Parse would be reporting there are no registered devices despite the presence of installations.
Details:
Parse 1.6.0
Unity 5.1.0.f3
I developed an App that receives push notifications from Google Cloud Messaging, messages are sent to broadcast from a server in php through the procedure CURL. Everything is working fine but a device (Android 4.3) a few days does not receive notifications from GCM.
Question: Is there any way (in PHP) to reclaim such registration id are still valid or need to be renewed?
I know the id registration must be renewed when the app is updated or uninstalled and then reinstalled it in this case was not made any changes.
In this device other notifications arrive correctly (whatsapp, sms).
For my app does not have disabled notifications.
I have not updated or uninstalled the app for groped to understand whether the problem is the device or something more obscure.
Now GCM return this (not error):
{"multicast_id":6846627542248171696,"success":3,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1442178661471816%5ed68546f7f47ecd"},{"message_id":"0:1442178661471814%5ed68546f7f47ecd"},{"message_id":"0:1442178661472121%5ed68546f7f47ecd"}]}
The DEVICE not receive push notification is 3 but CURL operation return true.
Do you have any suggestions?
I have verified that the problem was related to the device and not the Bees google for the non-receipt of the message.
An operation CURL but can not return the entire state of the message because of the fact that it is a synchronous operation. I noticed from the console that can pass several minutes before the device returns the code Accepted.
The only way to confirm the message was received by the device seems to be an asynchronous operation with an appropriate Java server.
I am using Uniqush to send GCM messages to an app I'm developing, and so far this is working well. However, for obvious reasons I am uninstalling and reinstalling the app as I develop, and it's re-registering for GCM with each new install.
I understand GCM is supposed to handle this automatically:
http://developer.android.com/guide/google/gcm/adv.html#unreg
if a message can't be delivered to a device, it sends an error to the server, which handles it. Unfortunately (even after sending a test push message while the app wasn't installed) I am getting duplicate messages to my device.
Is this a failure in Uniqush, my program, GCM, or some combination of the three?
If notifications are sent to a device while it has the app uninstalled, eventually the duplicates clear.
Given your description, I am unable to reproduce your situation. Here are the steps to try to reproduce it:
Install the test app on my phone and push notification to it using uniqush. Correct. Uniqush's log shows it is successfully delivered and my phone shows the correct result.
Uninstall the test app.
push another notification again using uniqush. Uniqush's log shows the message saying the user is unsubscribed the service: [Unsubscribe][Info] 2012/12/21 19:18:08 [UnsubscribeRequest] RequestId=3992a14e4987e94e3ce16bb7394ee06d2d9e7231 Success
DeliveryPoint=gcm:47e6551857be173b1418e56b63dbdb8cd58c94a2
Then push one more notification to the device, uniqush says it cannot find the device (because it has already been removed.)
Check the database using redis-cli, the device's information is no longer stored. It is successfully unsubscribed.
However, I did found some problem: if you check the error message returned from uniqush from HTTP, then you will see Success on the second notification. I have already fixed this bug in next release. It will be online soon. (If you are interested in that, check the .deb package )
In fact, uniqush is designed to be able to handle such situation so that the user don't need to care about unsubscription, device token/registration id update, etc.
If you have any future question, please feel free to comment or contact me.
I just added C2DM capability to my Android App.
At the moment the following happens if C2DM is started in my App.
My App sends the registration Intent
The answer broadcast is received by my app
The device token is retrieved from the intent and sent to my server
From that moment everything is working fine. The client receives the push notifications etc.
A problem occurs if the following hapens:
The user uninstalls the application without disabling push. (Completely deleting it not only updating)
The user reinstalls the application
If after step 5 a push notification is sent my app still receives this notification.
It seems that the token which was retrieved from the previous install is still active and is reconnected to the new instance of my application.
This leeds to the following problem:
A user who reinstalls my app but has no intention of receiving push notifications has no possibility to remove himself from the service because the new instance of the app has no way to unregister the old token from my server.
Is this a bug in the C2DM system or is something wrong in my setup?
Update
I followed Berdons advice and did the following:
For testing purposes only start an unregister Intent every time my app starts up.
After I send the unregister intent no push notification from my server is sent to my application. That seems to do the trick, but if I now go the C2DM Settings Screen and turn on push notifications for my app all the old tokens get active again and I receive information that I did not register for in the current installation of my app.
Next Update
It seems I'm not the only one with this problem:
Android C2DM : Duplicate message to the same device and App
I hoped that Google would manage those tokens in a way that old tokens from the same device get disabled after a new one was issued. I also expect that after I sent an unregister Intent all tokens for that application and that device are marked as invalid or deleted from the Google Server for ever. If this is somehow a design decision by Google for special use cases I don't see please enlighten me.
We now found a solution that should work in most of the cases.
The server adds the C2DM registration id as a data field with every C2D Message.
The device now only shows a notification if the token in the message and the token that is stored in a pref file match. That way we guarantee that we don't show messages for device tokens that were obtained by previous installs.
If the tokens do not match we found an old token that should not be active anymore. We now mark the token on our own web server as inactive to prevent the server from sending more unnecessary C2D Messages
This solution enables us to show only relevant data without the need to store a unique user id.
In my C2DM implementation, each user's device token is saved in a database against their UDID and the package name of the app (among other things). The UDID and package name form the primary key, meaning that the table can list multiple apps from the same device (UDID). When a user runs a particular app, the device token is recorded, and if they uninstall and re-run the app, the new device token would be recorded over the old one. We also have columns to record whether push is active for that particular app/device combo, and which types of push messages the user has enabled/disabled.
When the time comes to send a push for a particular app, no UDID will be registered more than once (since these two fields form the primary key), and therefore only the latest device token will be used. Furthermore, our query only returns the rows that have push messages enabled.
This solution should solve your problem because it prevents you from sending the push to both device tokens. I hope this helps!
More like an unexpected "feature". You might consider issuing an unregister request on the "first run" (first run ever) of your application to prevent this from occuring.
Update
You could could do the work of differentiating between different C2DM messages by using the collapse_key (or anything of your own creation) as an identifier. Update it between registrations and pass it to the device following registrations, unregistrations and messages.