I trying to understand how FCM (Push notifications) works... and that is very differ with Web applications...
What I did →
Register new project in Firebase
Added App com.google.firebase.quickstart.fcm and download google-services.json
Built App using google-services.json in Android Studio
Install APK on my device
Go to https://console.firebase.google.com/project/{PROJECT_NAME}/notification and sent new notification
And... nothing happens
So my questions are
As I know here is two ways to send notification: a) use device token and send direct notification, b) subscribe device to topic at client side.
But
a) When I try to create New notification in firebase console, here is no field where I will be able to insert device token. Here is Target → Target user if → App → com.google.firebase.quickstart.fcm. So do I need to know device token or I can send notifications to all clients that have my app installed on their devices?
b) When I trying to send message on weather topic nothing happens. Even if I pressed button Subscribe to weather (In manual you may find Subscribe to News, but actual version button is weather)
Is there any way to check (especially at server side) if my device registered in FCM or not?
What is the most effective way send same contents on big number of devices (for example 50000) with minimum time lag? Try to loop over device tokens (1000 tokens per request) or using topics? Is there any other ways?
Actually my backend is AWS SNS in pair with FCM, so if you can answer about most effective way in case of SNS + FCM that will be brilliant
I don't know... any suggestions? I'm a web developer (REST, etc...) and have zero experience with mobile apps
1- You will need to store the current device tokens in a database to then loop through each one to send a message.
Topics need to be subscribed to from the client side and have limited use
2 - you should be storing it in a database, sending an FCM will yield an error if it is expired, which you will have to remove and wait for the client to re-send a fresh token
3 - Topics is common practice, have every device listen to a 'global' topic but there is a native delay as FCM is designed for maximum output rather than time sensitivity. for that, you will need external services that specialize in high speed messages.
4 - you can invoke cloud functions to invoke other firebase services, even the rest API and onTrigger listeners on a database are valid
5 - FCM is great, but it's not the best as it was created as a general solution. a combination of different CM services is recommended, especially if you have time-sensitive needs. but they do come at a cost while FCM is free.
Related
I am working on an app, which requires Android push notifications to be implemented.
I have decided to use Firebase Cloud Messaging directly; without using any other abstraction such as AWS SNS or Pusher.
I would like to avoid storing and managing device tokens in the backend, by using the following approach.
In the android app.
When the user logs into the android application, obtain device token but not send it to the server.
Subscribe to a topic that is based on a agreed convention, such that the topic is unique to that user.
On logout unsubscribe from the topic.
In the Server.
Whenever a situation arises to send a notification to particular user, send push notification to the topic, that is based on the convention.
I would like to know if this is a viable strategy to avoid managing device tokens ?
Case against using topics.
From the official docs.
Based on the publish/subscribe model, FCM topic messaging allows you to send a message to multiple devices that have opted in to a particular topic. You compose topic messages as needed, and FCM handles routing and delivering the message reliably to the right devices.
For example, users of a local weather forecasting app could opt in to a "severe weather alerts" topic and receive notifications of storms threatening specified areas. Users of a sports app could subscribe to automatic updates in live game scores for their favorite teams.
I see that topics are recommended, when multiple devices are to be notified. But I have decided to create a topic per user, this would mean most topics would end up getting subscribed by only one device; Is this approach ok ?
I see that topics are recommended, when multiple devices are to be notified
Yes, multiple devices that have something common to listen to, which is the topic. Topics are used for messages that could be received by the general clients since it is public -- i.e. anyone could subscribe and receive messages sent to it.
What is advised to use for multiple devices, but for the same user is to use Device Groups (see my answer here for tips on Managing Device Groups). However, if you don't mind the "topics being public" part, then your approach should be fine.
Yes, Here required device tokens if we want to send push notification whoever installed your app.
My research we can save device tokens in back end at first time installation of your app that is better according to my understanding so that we can easy to send push notification across all devices.
I am doing a prototype that involves messaging between clients.
What I want to do - from MyApp on device1, able to send message to MyApp on device2. Device2 should receive this and show a notification.
I don't have my own application server to push notifications from GCM to GCM clients.Is this possible ? How to do it ?
What I investigated - PubNub, which has a trial license that seems to answer my need to send messages on a channel without needing a server.
This discussion at SO didn't help much.
sending client to client messages without server interaction
Can anyone suggest better ways ?
You basically have to use a server in one way or another. I think Firebase would be perfect for your purposes. It has an Android plugin you can use that will basically alert your app when something changes in the database. Here is the documentation for that feature. Take a look at this example for implementation. Before you can use the plugin, you need to create an account and whatnot (basic one is free). Here are the instructions.
PubNub Realtime Messaging and Push Notifications
(server not required)
With PubNub, you do not need your own server to do the realtime messaging or the mobile push notifications. You likely have your own server for your database (MySQL or similar, traditional RDBMS, a No SQL DB like MongoDB, or a realtime DB sync, like Firebase) to authenticate users and such.
For realtime DB or non-DB type change notifications and signaling (any type of realtime messaging), PubNub makes is super simple to receive messages in realtime with a mobile push notification fallback in one publish action. So the GCM message will be sent along with the realtime message. If the app is actively running, you get it in realtime (< 1/4 on average - typically faster) and the GCM message will be received if the app is not active (background or not started at all).
And PubNub's free plan is not a trial (anymore). It is free (including all add-ons) for as long as you stay within the free plan limits.
See the PubNub Android docs for more details and contact PubNub support if you have any further questions with getting started or getting answers to any questions you have as you progress with your app implementation.
Another possibility is to use the SMS.
Android Send and Recieve Messages
"Send Binary (Data) SMS
We can send binary messages (as opposed to text based messages that we covered earlier) to specific application ports using sendDataMessage(). According to this Stack Exchange thread data sms is one which is sent over 2G/3G as well as GSM. I’ve tested it with mobile data turned off and it works fine charging me the same amount, so not very sure on whether it uses 2G/3G or not, but generally the term data is used in telephony when it’s related to network (tcp/ip). Anyway, SMS’s are generally sent to a specific port on the device (which is probably port 0 [zero]). But using sendDataMessage() we can send SMS’s to some other random port on which our app can listen for incoming SMSs and do something with that. In this case the default messaging app will not store the SMSs in their inbox for both the sender as well as the receiver.
"
Can anyone help me with a way to send requests as a notification through my android app to all the users who have installed my application and then their responses are sent back to the user who sent the request.
I have read about GCM but I dont understand how can I register all the users to get their GCM registration ID and how can i simulataneously send a notification to all users..I may sound naive but I am completely new to this GCM concept and I dont think that it is the exact thing what I am looking for..
So,somebody please tell me how to send notifications(simultaneously on click of a button or something..) to all the users who have registered in my android app .
You will need to build a server component that keeps track of all registered users. This component will be an app that you write and expose in the cloud. There are many app-hosting services to choose from. Amazon EC2 is one example.
So the app flow would be something like this:
User launches your Android app.
Android app registers itself with GMC. GCM will respond with a token that represents that device.
Android app POSTs that device token to your cloud application.
Cloud application saves that token. The app should now have a list of tokens that represents all active devices running your app. (of course you may want to have an expiration policy - i.e. remove all tokens corresponding to devices you have not heard from in say 30 days).
One of your app users posts a message that s/he wants to broadcast.
Your Android app responds by sending a request to your cloud application.
Your cloud application responds to this request, by making a request to GCM. In this request (or series of requests), the app will include all device tokens and the user-entered message.
GCM responds by pushing the message to all devices with your app (i.e. all of those that have register with GCM and received a token - see step 2).
If using GCM alone you would need to write a server component. I get the impression you don't want to do this. You could use Urban Airship push messaging, which will allow you to send out a message to all registered apps from the Urban Airship web portal. Urban Airship integrates with GCM (which is easy to setup). You would still need to add code to your app to handle the push notification the app receives.
http://docs.urbanairship.com/build/android.html
We are creating a mobile device management solution. We want to use Google cloud messaging(GCM) service to push notifications from server.
To use GCM, we need to create a Google API console project and enable the GCM service. Also, we need to create a server key(API key) in this API console project which is used later to authenticate server to GCM. All the client applications register to GCM using SenderID (generated as soon as the project is created).
Problem:
For each of the customer, we would need to create a google account to provide GCM functionality (not sure if there are other ways). We need to automate the above process (creation of google account, creation of google API console project, enabling service, creation of server key and so on). In other words, customer should not see anything that is happening.
I tried looking for couple of days, I am not able to get much information.
1. Can we automate this process?
2. If no, do we need to do any license purchases from google to achieve this?
Any other way I can achieve this (enabling GCM for all the customers )?
Note: This is my first question. Apologies if there are any mistakes.
There is no need in such automation (which is certainly not wanted by google). For your need you only create one key on the console, in one project.
You customers register to GCM on the first launch of your app, which gives them a unique (per app & per device) key (regID).
Every time you send them messages (downstream) you target them specifying this regID. Every time your app sends a messages, the regID is automagically added by GCM client, so that your server knows who is sending.
More precisely:
You have several clients, identified by their clientID, with an installed tomcat-based server (client server).
Each client has several users, identified by a userID (input on UI, etc). This users are aware of the clientID they belong to. the couple userID/clientID is unique on the central server below.
You also have a central server, connected to GCM/CCS, backed with a DB, forwarding messages between a user and the associated client server.
When a devices registers, it gets the regID from GCM, and sends (via http or xmpp) its userID and associated clientID to your central servers which stores it, and sends it to the correct client server. Subsequent messages upstream work the same: your messages stanzas contain the userID, which allows to query the DB backing your central server for the clientID, and thus to forward the message to the correct client server.
Downstreams initiated by your clients send a message containing the actions and associated data to you central server, from the userID it checks if the user really belongs to the sending client, get the regID, and sends it to the correct device.
In this proposed architecture you have one key/project on the Google console, and multiple sets of users, each set being manage by its own server.
I have an app that runs across iOS and Android. I'm working to add push notifications to that app.
At a very high level, devices register with the Apple Push Notification Service (APNS) or Google Cloud Messaging (GCM) and receive a token. They then hand that token back to the server that's in charge of sending notifications. That server, when it wants to, sends a notification to APNS or GCM and says "send this notification to the devices with these tokens".
So, my apps need to be able to securely send their tokens to my server, and delete those tokens from the server when the user no longer wants to receive notifications. It's very easy to add a simple CRUD page on the server side which handles ?create=<token>, ?delete=<token>, etc.
But what happens when someone goes to my server and starts spamming random values for ?delete=<token> — it seems like they'd be able to just delete random device tokens at will?
I've thought about the "delete" case a bit more, and I think it should be easy: the app can just send along a generated public decryption key with the initial “create this token” request. That key can be stored against the token. When the app wants to delete, it can send along the encrypted copy of the token, and the server can match the token against the decrypted copy, verifying that the app must possess the stored public keys matching private encryption key (which is a secret known only to the app).
What happens when someone starts spamming random values for ?create=<token> — do they get to just fill up my database table with fake device tokens?
I can't see an easy answer — rate limiting "create" requests from any single IP address seems to be about the best we can do without registration involved. That obviously isn't going to help us against any distributed attack.
Ideally I'd like to enable push notifications by default / without the user having to "register" or anything like that. My first thought is that each device token should be tied to a known canonical Apple ID or Google account — but how do I stop users from falsifying those? Do devices come with a certificate that I can get an authoritative public key for (in which case each device can just get a row tied to its public key)? What's the best way for me to implement authentication here?
The solution to the problem for android can be found Here. In brief it can be summarised as
You use the GoogleAuthUtil class, available through Google Play
services, to retrieve a string called an “ID Token”. You send the
token to your back end and your back end can use it to quickly and
cheaply verify which app sent it and who was using the app.
A lot of good questions here. :)
Let me try to break it down.
General thoughts
I don't think it's good idea to mix Android and iOS here. High level push notification architecture is similar between them, but that's about it.
Tokens are long (as I remember iOS token is uuid). So, there is no way to guess it by just randomly trying different values. So, I would say ?delete=<token> case is non existent.
The case of ?create=<token> is more realistic. First of all, somebody can bring your server to knees, registering millions of tokens. Also, if you are sending some sensitive information via push notification, you may don't want it to be received by non authorized app users.
Android solution
For Android it's easier.
As soon as you get a token on the server, just send a push message with some randomly generated string (store it in DB). Your application on a device will get this string and will send it with the token to the server (via second web call). And your server make sure that it will send anything to this token only after it was authenticated.
This way you rely on GCM ability to deliver messages to correct clients to make sure that authentication information (random string) is delivered to your application.
iOS solution
The problem with iOS is that push notification doesn't automatically trigger code execution, if the application is suspended or in background.
So, if you will try to do the same thing and a user accidentally exits your app, while push notification is being deliver than your app will never see it.
You can do following (the idea is basically the same as for Android, only with difference that we may need to require user interaction)
Push notification with a message "Please run my app and enter X" (where X is some random string)
This way, if your app is in background, a user will click on this message, enter X and your app will authenticated to the server.
In the case, if app is in foreground, it will get push payload and can authenticate directly.