We provide a service which has collected a lot of GCM registration ids over the last couple of years. We are wondering how many of these are still being used. We send millions of push notifications but we don't know which actually arrives on a device.
I followed the advice of some answers here on StackOverflow to check the validity of registration ids/push tokens using a dry_run flag.
That works fine to sort out tokens that are not valid (like asdf). But I also checked some ids of mine, all of them were valid. Even my oldest token (> 3 years old) of a device that is not in use anymore for 2 years now. Sending notifications to this token will never arrive on a device for sure.
Any idea on how we can check if a token/registration id still delivers notifications?
Thanks!
After some days I came across the FCM statistics panel in the google's developer console. It shows how many messages are sent and how many could be delivered to devices. This does not allow me to judge on individual tokens, but it gets me a general picture.
https://support.google.com/googleplay/android-developer/answer/2663268?hl=en
Related
I run an Android app that has users that wish to stay registered for push notifications indefinitely, and many use the app for years. I switched over my push notifications to Firebase last spring, and I'm now getting a significant number of users complaining who, after receiving notifications for months without issue, no longer receive notifications (when I try to send to the tokens I have in my database for them, I get either a InvalidRegistration or NotRegistered, not sure which tbh).
Is anyone else having this issue, and is it an issue with Firebase FCM itself? Perhaps onTokenRefresh isn't being called when it should be at times or something? (I'm certain that my code to give a refreshed token to the server is solid - I had no problems for years with the old GCM, although I had to have a bunch of hacks to re-register periodically in addition to when the user updated the app or the OS)
I see that FirebaseInstanceId.getInstance().getToken() can throw an IOException, perhaps that is killing my onTokenRefresh method before it can start sending the token to the server? Do robust apps take this possibility into account and have a mechanism to retry on failure?
Basically, just looking into any insight into why this is happening, if others are having the same issue, and any workarounds people have found. At the end of my rope over here:/
Let's say I have an Android app with 100 users that I don't know personally. Is it right to make each one of them subscribe to topics like FirebaseMessaging.getInstance().subscribeToTopic("<company_id>_<user_id>"); so I can address them and send notifications for one or two specifically or there is a better way to do that?
If you intend to send a message to specific users only, you could simply go ahead and use to or registration_ids when targeting the specific users. registration_ids has a limit of 1000 tokens per request.
As per the topics, it was designed to easily send messages to its subscribers. Depending on your use-case, it could be fine to subscribe them. However, you should still keep the registration tokens for each user in case you need to send specific messages.
It all depends on your goal.
Anyone can subscribe to a topic, so you should only use those for sending messages targeted-but-public messages. While you can counter this a bit by making the topic names hard to guess, the inherent behavior of topics is that you lose control over precisely what devices are targeted in return for having to write less code.
If you send to a token in your own code, you determine precisely who receives the message. But you will have to run the code that maps the message to the tokens yourself.
I think the answers are pretty clear, I would only like to add that, this method of subscription it can be easily combined with the Firebase web console. If you want to quickly send a message to any topic, the topic is created on registration, so you only have to know the topic name.
In the Firebase Web Console, you can find the target, an application, a token for a device or a topic. If you choose a topic, just write the topic name. There is an error which always says there is no topic, disregard it, and click send, the push will be sent and the subscribers will get their notifications.
Probably a GCM newbie question...
I more or less understand how to subscribe to topics and how to send messages to topics. But I was wondering : how does a topic gets created ?
From the docs I read, I guess a topic exists when at least one app subscribes to it, correct ? (As far as I could see there's no specific api to 'create' a topic).
I also noticed that it should be possible to register apps to a topic not from the app itself, but from an app server (by sending a HTTP POST message to a specific URL). Does this work the same way ?
E.g. if the topic doesn't exist when subscribing, it will be 'created'?
As far as I can tell, yes, whatever topic name a client app uses when subscribing, will get created. Even if it is "sdfgklfhjashfgkjas" and purely accidental.
I have seen no mention of deleting topics. I guess unused topics don't really cause Google any problems; they don't take up much space.
On the server side, you can force an app instance to subscribe to a topic by passing the token in a http POST as mentioned in the GCM documentation. Ditto for unsubscribing from a topic.
Bear in mind there are limits on topics which could cause problems for popular apps.
How does a topic gets created?
There is no detailed explanation in the documentation on how topics are created but according to the documentation.
An app can subscribe to different topics defined by the developer. The app server can then send messages to the subscribed devices without having to maintain topic-subscribers mapping. Topics do not need to be explicitly created before subscribing or publishing—they are automatically created when publishing or subscribing.
From the docs I read, I guess a topic exists when at least one app subscribes to it, correct ?
I think this is the case because in order to create a topic you will have an app subscribe to it.
I also noticed that it should be possible to register apps to a topic not from the app itself, but from an app server (by sending a HTTP POST message to a specific URL). Does this work the same way?
Yes your app can subscribe to other topics not necessarily related to your app as long as you pass the GCM registration token and topic name. See Subscribe to a topic.
I have one single Gmail account signed up for C2DM.
What I would like is that my app, thanks to this account (after having requested registration IDs and auth tokens for each device), could be able to provide messages to all the devices in which the app is installed.
I want to know if is it possible to use the C2DM in this way..
Thanks a lot
(for any details, just ask me.. )
ps I made the c2dm work on the emulator, but of course I cannot try what written before because I would need several phones..
Going off your question and comments, it sounds like you're just wondering if you can send c2dm notifications to an indeterminate number of devices using only one sender id.
That is exactly the way c2dm is supposed to work. You create one sender id to use on your backend servers, and that sender id is used in your app to register for c2dm notifications. Your backend then gathers all registrations ids and uses your one sender id to push notifications interested parties.
If I understood your issue correctly, the answer is: you can't.
You will have to send one http request, to google servers, for each device you want to reach.
There's no way to broadcast a message to all the users who have registered to your service.
It' frustrating because in my case I send a newsletter for all my users, so opening a connection to millions of users is expensive.
To solve the scalability issue I have created a simple appengine map-reduce task that loops through all the user registrations and create the http connection to the google services, it's the fastest you can go because it dynamically instantiate new servers for your delivery needs.
C2DM has been deprecated. GCM has replaced it, and it allows you to send messages to 1000 devices with one HTTP POST.
C2DM->GCM Migration Guide:
http://developer.android.com/guide/google/gcm/c2dm.html
So I have a strange problem, my app has C2DM setup and and it works for the most part, however there is quite a few people who never get registered. So the flow is as follows. On login, we make the registration request, when we get the response on that it submits the registration id to my back-end server and stores it in the database. For some reason I can see that some people logged in just fine, but I never received the registration id on the server, any ideas? I haven't be able to reproduce this my self, but it is affecting a lot of people using my app. Any suggestions on how I can make this more reliable? Because when the C2DM does not work they tend to not stay and use my application.
Any help or advice would be much appreciated.
What do you do on the client side if the registration fails? It could fail for a number of reasons. It'd probably be a good idea to send the status to your backend in failure cases so you can track that. Personally, The most common failures I see are due to not having a logged in google account or having background data turned off in settings.
Could the users in question be on unsupported (pre 2.2) devices?
C2DM in intended for android devices running Android 2.2(API 8) or higher that also have the Market application installed. However, you are not limited to deploying your applications through Market.
Also make sure you make the C2DM registration at very beginning of app start say splash screen. As the C2DM to register and obtain the REG_ID take about 3-4 sec depending upon the network connection.
Also make sure the devices that it is having problem that you reported might be showing the ACCOUNT MISSING:: OR ERROR IN REG_ID when C2DM registration works