blackjack blackjack - 24 days ago 16x
Android Question

How to push notification to client when Firebase has a new entry?

I wonder if it's possible to send push notifications to android mobile devices whenever Firebase gets added a new child on specific entity.
For example, let's say there's an entity on Firebase called Tasks. Whenever a new task is added to that firebase collection the "child_added" event is fired and then, in some way, a push notification is sent to a mobile client.
The trigger is the child_added event. However, I'm not sure if is feasible sending push notification right from Firebase events.


You can make a very simple node.js server or a java servlet (based on your language preferences) then using firebase server sdk you can add childEventListener. When value changes you can use FCM to send push notifications using http protocol. I am using this in my app and it is very feasable and reliable.

Note: If you are using this flow for an android app then using java server sdk will be beneficial as it is almost similar to what you have on android.

EDIT: After getting some spotlight on this answer I thought to share some more info regarding same.

//example node.js server as seen on this official firebase blog

var firebase = require('firebase');
var request = require('request');

var API_KEY = "..."; // Your Firebase Cloud Server API key

  serviceAccount: ".json",
  databaseURL: ""
ref = firebase.database().ref();

function listenForNotificationRequests() {
  var requests = ref.child('notificationRequests');
  ref.on('child_added', function(requestSnapshot) {
    var request = requestSnapshot.val();
      function() {
  }, function(error) {

function sendNotificationToUser(username, message, onSuccess) {
    url: '',
    method: 'POST',
    headers: {
      'Content-Type' :' application/json',
      'Authorization': 'key='+API_KEY
    body: JSON.stringify({
      notification: {
        title: message
      to : '/topics/user_'+username
  }, function(error, response, body) {
    if (error) { console.error(error); }
    else if (response.statusCode >= 400) { 
      console.error('HTTP Error: '+response.statusCode+' - '+response.statusMessage); 
    else {

// start listening

//example test java servlet which I made just to demonstrate this use case

public class MainServlet extends HttpServlet {
    * @see HttpServlet#HttpServlet()
        public MainServlet() {


         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
         *      response)
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {

            // Get context and then relative path to saved json config file from
            // firebase
            ServletContext context = getServletContext();
            String fullPath = context.getRealPath(FILE_PATH_FOR_JSON_SERVER_AUTH);

            // Check if we actually got a file from above path
            if (fullPath != null) {

            } else {


            // Setup connection to firebase database here
            FirebaseOptions options = new FirebaseOptions.Builder().setServiceAccount(new FileInputStream(fullPath))

            // Check to make sure we don't initialize firebase app each time webpage
            // is refreshed
            if (!exists) {

                // If firebase app doesn't exist then initialize it here and set
                // exists to true
                exists = true;


        // Call this to begin listening *notify* node in firebase database for notifications
            addNotificationListener(request, response);


         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
         *      response)
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {

            // Build apache httpclient POST request
            HttpClient client = HttpClientBuilder.create().build();
            HttpPost post = new HttpPost(ENDPOINT_URL);

            //Get the required id stored in lastMsgId tree map here
            if (!(chatLogs.getLastMsgIdTreeMap().isEmpty())) {

                sendToID = chatLogs.getLastMsgIdTreeMap().firstKey();
                lstmsg = chatLogs.getLastMsgIdTreeMap().get(sendToID);

            //Set up a unique id with concatenating sendToID and lstmsg
            uniqueID = sendToID + lstmsg;
            //Set up a previous id to check with unique id. To avoid instant duplicate notifications
            previousID = fcmHelper.getPreviousid();

            // Check uniqueId and PreviousID beforeSending
            if (!(uniqueID.equals(previousID))) {

                //Check if device token and user Id hashmap is not null
                if (!(userLogs.getUserIdAndFcmTokenHashMap().isEmpty())) {

                    //Get the device token of sendTo Id here
                    deviceToken = userLogs.getUserIdAndFcmTokenHashMap().get(sendToID);

                    // Create JSON object for downstream data/notification
                    JSONObject mainNotificationJsonObj = new JSONObject();
                    JSONObject outerBaseJsonObj = new JSONObject();
                    try {

                        // Notification payload has 'title' and 'body' key
                        mainNotificationJsonObj.put(TITLE, NEW_MESSAGE_RECEIVED);
                        mainNotificationJsonObj.put(BODY, lstmsg);
                        mainNotificationJsonObj.put(NOTIFICATION_SOUND, NOTIFICATION_SOUND_TYPE_DEFAULT);
                        //mainNotificationJsonObj.put(TAG, fcmHelper.getFcmTagId());
                        System.out.println("This is sentBy id =" + fcmHelper.getFcmTagId());

                        // This will be used in case of both 'notification' or 'data' payload
                        outerBaseJsonObj.put(TO, deviceToken);

                        // Set priority of notification. For instant chat setting
                        // high will
                        // wake device from idle state - HIGH BATTERY DRAIN
                        outerBaseJsonObj.put(PRIORITY_KEY, PRIORITY_HIGH);

                        // Specify required payload key here either 'data' or
                        // 'notification'. We can even use both payloads in single
                        // message
                        outerBaseJsonObj.put(NOTIFICATION, mainNotificationJsonObj);
                    } catch (JSONException e) {


                    // Setup http entity with json data and 'Content-Type' header
                    StringEntity requestEntity = new StringEntity(outerBaseJsonObj.toString(),

                    // Setup required Authorization header
                    post.setHeader(AUTHORIZATION, FIREBASE_SERVER_KEY);

                    // Pass setup entity to post request here

                    // Execute apache http client post response
                    HttpResponse fcmResponse = client.execute(post);

                    // Get status code from FCM server to debug error and success
                    System.out.println(RESPONSE_CODE + fcmResponse.getStatusLine().getStatusCode());

                    // Get response entity from FCM server and read throw lines
                    BufferedReader rd = new BufferedReader(new InputStreamReader(fcmResponse.getEntity().getContent()));

                    StringBuffer result = new StringBuffer();
                    String line = "";
                    while ((line = rd.readLine()) != null) {

                    if (response != null) {

                        // Print out the response to webpage
                        PrintWriter out;
                        out = response.getWriter();
                        System.out.println("This is Result - " + result);
                } else {
                    //Abort this process if conditions not met



         * This is the main method to be called to setup notifications listener on server startup

        private void addNotificationListener(HttpServletRequest request, HttpServletResponse response) {

            //Initialize Value event listener 
            lastMsgListener = new ValueEventListener() {

                public void onDataChange(DataSnapshot arg0) {

                    // Clear idLastMessagerecivedhash map if not null
                    if (lastMsgIdTreeMap != null) {

                    //Get lastmsg to be sent as notification here
                    lstmsg = (String) arg0.child(LAST_MESSAGE).getValue();

                    //Get sendToID here
                    String sendToID = (String) arg0.child(SEND_TO).getValue();

                    //Get Sent by ID here
                    sentBy = (String) arg0.child(SENT_BY).getValue();

                    //Set fcmTag ID here

                    //Check if lstmsg is not null
                    if (lstmsg != null) {

                        // Create lastmsgTimestampHashMap here
                        lastMsgIdTreeMap.put(sendToID, lstmsg);

                    //Check for null again
                    if (lastMsgIdTreeMap != null) {



                    try {
                        doPost(request, response);
                    } catch (ServletException e) {

                    } catch (IOException e) {



                public void onCancelled(DatabaseError arg0) {


            //Set up database reference to notify node here
            messageRef = FirebaseDatabase.getInstance().getReference().child(NOTIFY);

            //Add value listener to database reference here


"Java servlet is just a personal test. Some parts have been edited or removed to only give an idea about it's setup this is in no way production ready servlet please don't just copy - paste. I encourage you to understand and build your own."