SEND FIREBASE CLOUD MESSAGES (FCM) TO YOUR
DESIRED ANDROID USERS USING NODE JS SERVER
Architecture:
As the figure says, we will send notification
messages from our android set to our own server (say Node js web app). In the
Node js web app we implemented the admin sdk of Firebase Cloud messaging (FCM)
server. The Nodejs web app communicates with the firebase cloud server using
its app credentials. The FCM (Firebase Cloud Messaging) server now serve the
users of defined categories.
[This article should be read as the appended
section of SEND YOUR FIRST ANDROID NOTIFICATION USING FCM (Firebase Cloud
Messaging)]
1. In your Firebase console go to Project Settings>Service
Accounts
2. In the Service Accounts window click
Generate New Private Key. Then in the confirmation window click Generate Key.
3. The Google Credential json file will be
downloaded to the downloads folder of the browser.
Keep this file safe.
4. We need to put this file in the project root
of our Node js web app.
5. SETUP THE NODEJS WEB SERVER
Now install firebase admin sdk in our server.
In my case my server is an apache shared
server. I have node js setup tool in it.
(i) first create a folder in my shared server
root directory. Under it I will create my base directory for my nodejs web app.
(ii) it is better to create a demo app in our
local WAMP or LAMP server with npm init.
(iii) the main app.js file along with
package.json will be created there.
(iv) now upload this app.js along with
package.json to our shared server base directory.
(v) Now go to nodejs setup.
(vi) specify Node js app root directory in
Application root.
And put the application url.
(vii) Application startup file(app,js) &
log file
(viii) click on Edit under Run NPM
Install.
(ix) Here enter in the dependency section the
firbase-admin as following:
“firebase-admin”: “”
(x) Now install packages by clicking Run NPM
Install.
(xi) After successful installation open app.js
and add the following code in app.js file:
var express = require('express')
var admin = require("firebase-admin");
const port = 2388;
app.get('/', (req,res)=>{
res.status(200).send("Hello World")
})
app.listen(port, () =>{
console.log("listening to port"+port);
})
(xii) Save app.js and restart the web app from
Node js setup.
(xiii) Setup the subdomain for your web app.
Make https redirect to it. (xiv) Now in the browser test your web app by typing
your (sub)domain name.
This will show now Hello World on the browser.
It proves that our web app setup is correct and
working.
6. Now we have Google Credential json file
containing firebase keys stored in the base directory of our web app.
7. Now inside the app.js add the following code
to initialize the Firebase Admin SDK for messaging.
var admin = require("firebase-admin");
var serviceAccount = require("./myTopic-firebase-msg.json");
admin.initializeApp({
credential:
admin.credential.cert(serviceAccount),
databaseURL: "htts://<your
firebase database>.firebaseio.com"
})
Here myTopic-firebase-msg.json is the json file
I downloaded in the step 3 and renamed it. I put this file in web app’s base
directory.
Also the initialization requires a database url
to the realtime database (rtdc) of your Firebase Account (You will get it from
Real Time Database section on your Firebase console).
8. Further put a module like below to accept
request from the messaging app that controls the notification to all users.
app.post('/firebase/notification',
(req, res)=>{
var topic;
var title;
var message;
var body = [];
req.on('error',
(error)=>{
console.log(error);
}).on('data',
(chunk)=>{
body.push(chunk);
}).on('end', ()=>{
body =
Buffer.concat(body).toString();
res.on('error',
(err)=>{
console.error('Error
Occured :'+err);
});
var json =
JSON.parse(body);
topic = json.topic
title = json.title
message = json.body
const messaging =
admin.messaging();
var payload = {
notification:
{
title:
title,
body:
message
}
};
messaging.sendToTopic(topic,
payload)
.then(result=>{
Console.log('The
response: '+result)
});
res.send('Its OK..');
res.end();
})
})
Here be careful to construct the right payload with notification
and topic. This payload will reach to the end users.
9. Now save the app.js file. Restart the Node
js web app from nodejs setup.
10. Now make the following changes in our
message sending android app:
In your MainActivity do the following changes:
public class MainActivity extends AppCompatActivity{
protected void
onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout);
-------- --------- ------
Button btn = findViewById(R.id.sendMsg);
Btn.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v) {
AsyncTaskClass asyncClass = new
AsyncTaskClass();
asyncClass.execute();
}
});
}
class AsyncTaskClass
extends AsyncTask<Void,Void,String> {
@Override
protected void
onPreExecute() {
super.onPreExecute();
}
@Override
protected void
onPostExecute(String string1) {
super.onPostExecute(string1);
}
@Override
protected String doInBackground(Void...
params) {
ServerUploadPath
= "https://your.domain.com/firebase/notification";
String topic =
"urgent";
String
title = "Test Notification";
String
body = "Meeting called at 8:30 pm";
QString = makeMessageString(new
MsgToSend(topic , title, body));
String finalData
= sendData(ServerUploadPath,QString);
runOnUiThread(new
Runnable() {
@Override
public void
run() {
//process
the response finalData
}
});
return finalData;
}
}
private String
sendData(String requestURL, String QString){
final
StringBuilder stringBuilder = new StringBuilder();
try {
URL url;
HttpURLConnection
httpURLConnectionObject ;
OutputStream
outPutStream;
BufferedWriter
bufferedWriterObject ;
BufferedReader
bufferedReaderObject ;
int respCode ;
url = new
URL(requestURL);
httpURLConnectionObject = (HttpURLConnection) url.openConnection();
httpURLConnectionObject.setReadTimeout(19000);
httpURLConnectionObject.setConnectTimeout(19000);
httpURLConnectionObject.setRequestMethod("POST");
httpURLConnectionObject.setDoInput(true);
httpURLConnectionObject.setDoOutput(true);
outPutStream =
httpURLConnectionObject.getOutputStream();
bufferedWriterObject = new BufferedWriter(new
OutputStreamWriter(outPutStream, "UTF-8"));
bufferedWriterObject.write(QString);
bufferedWriterObject.flush();
bufferedWriterObject.close();
outPutStream.close();
respCode =
httpURLConnectionObject.getResponseCode();
if (respCode ==
HttpsURLConnection.HTTP_OK) {
bufferedReaderObject = new BufferedReader(new
InputStreamReader(httpURLConnectionObject.getInputStream()));
//StringBuilder stringBuilder1 = new StringBuilder();
String
received;
while
((received = bufferedReaderObject.readLine()) != null){
stringBuilder.append(received);
}
Handler
handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public
void run() {
Toast.makeText(MainActivity.this, stringBuilder.toString(),
Toast.LENGTH_LONG).show();
}
});
}
} catch (Exception e)
{
e.printStackTrace();
}
return
stringBuilder.toString();
}
private class
MsgToSend{
String topic;
String title;
String body;
public
MsgToSend(String topic,String title, String body){
this.topic =
topic;
this.title =
title;
this.body = body;
}
}
private String
makeMessageString(MsgToSend msg){
Gson gson = new
Gson();
Type type = new
TypeToken<MsgToSend>(){}.getType();
String rjson =
gson.toJson(msg,type);
return rjson;
}
}
11. In the user’s client Android app keep the FrebaseMessageReceiver
class unchanged. (This class we created earlier in the previous section -SEND
YOUR FIRST ANDROID NOTIFICATION USING FCM).
Also, In the main launcher activity onCreate
method must add the following code to subscribe the user for definite topic.
FirebaseMessaging.getInstance().subscribeToTopic(topicname);
To unsubscribe the topic topicname user app
must call unsubscribeFromTopic(topicname);
FirebaseMessaging.getInstance().unsubscribeFromTopic(topicname);
Note:
12. This change in user’s client android app
will enable it to receive FCM messages based on its subscribed topic.
Now Install client android app in user’s device
and install the sender app to your device. On clicking the button on sender app
push notification will be served to those user’s app who have subscribed to
topic “urgent” (as I have mentioned “urgent” as the topic in query string
(QString) in my sender’s app. This query string is collected by our nodejs web
app and extracts the topic from this query.).
FURTHER READING: HANDLING RECEIVING
OF FCM MESSAGES IN ANDROID IN EFFICIENT
MANNER.
No comments:
Post a Comment