Send firebase cloud message from client without exposing API secret - android

I'm developing a new chat application that currently works with firebase realtime database and cordova.
I was looking for a backend-less solution since my currently working app doesn't need any server at all apart from a tiny server that its only function is to provide with temporal authorization tokens for the clients.
This tokens allow the client to work directly with firebase without the need for a more expensive and loaded server, and still have a central control for the usage of the app.
By reading the new firebase documentation I believe that the notifications and the firebase cloud messages app can't be used by the client side to post messages, only to listen notifications since all the send message examples expose the server API key, which obviously can't be on the client side.
Is there a way to issue temporal tokens from a central server that can be used by the clients to send messages instead of having to send all the messages to the server and then back to the other devices?
Thanks

Sending downstream messages to devices with Firebase Cloud Messaging requires access to the authorization key. For that reason it should run in a trusted process, such as on hardware you control.

Cloud Functions for Firebase was launched today, which would solve your problem! You can initialize the firebase-admin SDK within your functions code (which runs on Google's servers, not client side), and use it to access FCM. That way you can send messages in response to new database items, or in response to HTTPS requests.
Here's an intro to Cloud Functions for Firebase: https://firebase.google.com/docs/functions/
Here's how you can use firebase-admin to send FCM messages:
https://firebase.google.com/docs/cloud-messaging/admin/send-messages

Related

Is a server required for Firebase Cloud Messaging?

I am currently developing an Android app and I would like to include Firebase Cloud Messaging.
I was planning to have a Raspberry Pi checking a website every 5 Minutes or so and sending push notifications when something changed.
In the official documentation they say that I need an 'app-server' in order to send messages via Firebase.
Does that mean I need to have my Raspi up and running as a server 24/7 and need a static IP / Domain for it?
Or is it enough to have my Raspi send the message via the Api (https://fcm.googleapis.com/fcm/send) as I only need downstream messages?
Any help and explanation would be highly appreciated as I can't find a definite answer in any thread or documentation.
You don't as such need an app-server for just one device. If you have some sort of internet connectivity on your Raspberry Pi device, all you need to do is make a request to the firebase API.
Firebase (Google servers) will handle the rest by pushing notifications to all the registered devices.
Sending downstream messages (messages to devices) requires that you specify the FCM server key. This key allows sending FCM messages on your behalf, so should only be used on environments you trust.
Typically this means a server that you control. But the recently launched Cloud Functions for Firebase can also serve as such a trusted environment. After all: only developers who have access to your Firebase project can access your Cloud Functions code, and those developers can already send messages using the Notification panel in the Firebase console.
Any device you control in your own environment is also fine as a trusted environment. It doesn't have to have a fixed IP address, since the FCM server typically receives its instructions through XMPP or (more commonly these days) through the Firebase Database. Both of these approaches initiate the connections from the trusted device to Google's servers, so can run without accepting incoming connections.
You don't need any server to implement FCM.

How to send message to the topic in Android

How to send a topic message via Firebase ?
I only found the way to send by using Firebase Console ,
as well as some ways about Post HTTP requests ,
but I don't understand how to do it in Android.
How can I write some codes in Android
to specify a topic which to target then send a message to the topic?
Thanks.
Sending a message to devices (so-called downstream messages) requires a HTTP call that specifies the server key. As its name implies, this key should only be used in environments you can trust. You cannot directly send a message from a device to other devices, including topics. This diagram from the Firebase Cloud Messaging documentation shows the flow:
So if you want to send messages from an Android app, you will have to:
create server-side code that the Android app talks to
have that server-side code call Firebase Cloud Messaging to send messages
have the Android app call your server-side code
One way to accomplish such a flow is described in our blog post Sending notifications between Android devices with Firebase Database and Cloud Messaging. It uses the Firebase Database to communicate with a server-side script that then calls FCM to send the messages to topics. The server-side code in this post is a Node.js script, since it was the simplest approach available when I wrote it.
But last week Firebase released Cloud Functions for Firebase. This allows you to run server-side code without managing your own infrastructure, which makes it a perfect fit for your use-case. In fact it is such a good fit that it's first in the documentation on use-cases for Cloud Functions for Firebase:
You will see that the approach in this sample is very similar to the one in the blog post: both listen for database writes to trigger sending FCM messages. Some of the changes in the sample compared to the blog post:
the sample replaces the Node.js script with a Cloud Function.
the sample sends to device tokens instead of topics.
the sample uses the new Firebase Admin SDK to send messages, instead of calling the FCM HTTP end-point
If your app is registered in Firebase console, you may send message not only via Firebase console but via either http client.
Here is code in Fiddler sending notification to "news" topic
Url:https://gcm-http.googleapis.com/gcm/send
Headers:
Content-Type: application/json
Authorization: key=[YOUR_APP_API_KEY]
Body:
{
"to": "/topics/news",
"notification": {
"body": "Hello dude!",
}
}
or use android app to send message
sample from github

What does "app server in my own environment" mean in Firebase Cloud Messaging documentation?

I am having trouble understanding the specific meaning of "app server implemented in my own environment" as used in this documentation on how to send upstream messages to the "Cloud" using Firebase Cloud Messaging.
Context
The documentation is saying that for me to send upstream messages, I need my own app server that implements one of two connection server protocols in HTTP or XMPP.
The Reason why I am confused
My expectation is that if I use Firebase, I don't need to create my own server. All of the backend stuff is handled by them. So to me, when they say I need to create my own app server in my own environment, it is contrary to my expectation and understanding and thus makes me second guess the meaning.
What it is I am specifically confused and asking about
What exactly do they mean by app server?
What exactly do they mean by "in my own environment"?
Another way my two questions could be asked is:
Is an app server in this context meaning just a typical app server that I write on my own using something like Node.JS/Express.JS and host on something like Digital Ocean? and/or
Is it something I need to do with other Firebase/Google Cloud products (eg Hosting or App Engine)?
Or could my implementation of the RealTime Database feature on my app be considered an "App Server" as it serves my app with data.
What I have done so far
Reading through every single documentation on Firebase relating to Cloud Messaging and browsing around Google.
I have had a solid read of what questions to ask and what to avoid. I am mindful that this question could be something with lots of varying and all correct answers so apologies if that offends one of the rules. But I have come across this question on Meta which suggests that asking for clarification on documentation is OK for SO.
Is an app server in this context meaning just a typical app server that I write on my own using something like Node.JS/Express.JS and host on something like Digital Ocean?
Exactly.
Is it something I need to do with other Firebase/Google Cloud products (eg Hosting or App Engine)?
Depends on your use-case. But for Firebase Cloud Messaging, when all you need is to send Downstream Messages, you don't need an App Server. You can just make use of the Firebase Console. If you need to send Upstream Messages, then you have to implement your own App Server.
Or could my implementation of the RealTime Database feature on my app be considered an "App Server" as it serves my app with data?
Not exactly. The Firebase Realtime Database stores the data you need, but the App Server needed for FCM is something that can process requests (Send (Downstream and Receive (Upstream)).
App notifications are sent by Firebase Cloud Messaging server. To send these notifications you will have to tell to which device notifications have to be sent.
So you will have to send the FCM Client ID from your backend server (Node.js, PHP server). You will get the FCM client ID when you integrate Firebase into your app. You will have to store the FCM client ID in your backend server like during registration of a user.
To send a notification to a device retrieve the FCM Client id from your backend server and send it to the Firebase cloud messaging server and it will check if the client id is valid and trigger a notification.

One to One Android Chat using Firebase

I need some clarifications.
I'm using Firebase realtime database.
Now I've to implement a realtime chat between two android devices. I need also push notifications.
So, the solution based on realtime database is to drop because if the app isn't running, it will not handle the onChildAdded event.
I read on the documentation that I can achieve my aim, using the upstream message from the device to the server.
Now, it's written also that we need an app server.
I just want to be clarified the need of the app server (XMPP or HTTP), and which is the entire flow of message m1 sent from the device A, and the notification on the device B.
In my opinion the app server should act as a man in the middle, so:
A ---> XMPP SERVER ---> FCM
FCM ---> XMPP SERVER ---> B
Is this the flow?
On the documentation I can't understand if I'm right or not.
If so, how do I send a message from the FCM back to the XMPP Server?
The notification message is sent from FCM to the client o from XMPP Server?
Please someone clarify me.
Other solution thought by me:
Since I find really powerful firebase realtime database, I thought these solution to walk around the problem:
Create an app server the is listening for onChildAdded and when it changes send a notification to client device.
Creating a background service on the client app listening to onChildAdded and create notification when necessary.
Even all, I don't like these solutions.
Just want to understand the standard and correct way to achieve my aim.
Firebaser and author of the article debated in the question comments here
To send messages to a device with Firebase Cloud Messaging, you need to specify your project's FCM Server Key. As its name suggests, this key should only be used in code that runs in a trusted environment: i.e. a server that you control.
To send device-to-device messages (such as in a 1:1 chat application where the receiving user is not necessarily online) you need two steps:
one user send an upstream message
the other user receives the downstream message
Using Firebase Cloud Messaging and your custom app server code, you can handle step 2. But that still leaves step 1: the user needs to send a message that somehow triggers your code on the app server. There are quite a few ways to do this.
For example you could implement an HTTP endpoint on your app server and have the chat application send the messages there too (in addition to sending to the database).
You could also implement an XMPP endpoint and have the chat application send the message there (again in addition to sending it to the database).
My article suggest yet another way, one that doesn't require implementing an endpoint at all. It uses a node.js script that runs on your app server and is essentially just a client to the database. Whenever this script detects a relevant chat message, it calls the FCM API and sends the downstream message.
This pattern of using the Firebase Database as your endpoint and then using server-side scripts is quite common when using Firebase. We documented it in our classic blog post Where does Firebase fit in your app? (as option 2) and in this article in the Google Cloud documentation.

How can i send a string from one android to another over internet

I want something similar to Facebook messenger and
I don't have much knowledge about web servers,can i use them?
It should be like
I accept on String from user and then upload it to my server and program the server to send it to other device and the other device gets notified by a background service
To create something similar to Facebook messenger, you could do a lot of things.
Just to start, in my opinion, a Serverless service. Firebase could be your solution or AWS (or any other service). It has a Push notifications and database where to store that Strings.
Firebase Cloud Messaging
Firebase Cloud Messaging (FCM) is a cross-platform messaging solution that lets you reliably deliver messages at no cost.
Using FCM, you can notify a client app that new email or other data is available to sync. You can send notification messages to drive user reengagement and retention. For use cases such as instant messaging, a message can transfer a payload of up to 4KB to a client app.
Firebase Realtime Database
The Firebase Realtime Database is a cloud-hosted database. Data is stored as JSON and synchronized in realtime to every connected client. When you build cross-platform apps with our iOS, Android, and JavaScript SDKs, all of your clients share one Realtime Database instance and automatically receive updates with the newest data.
Other way is open a socket in your Android app and handle all the events. I recommend you Socket.io to do that.
You could use node.js in your server to create a socket server and use the Android client.
http://socket.io/blog/native-socket-io-and-android/

Categories

Resources