You can create a very simple node.js server or java servlet (depending on your language settings), and then using sbk firebase server you can add childEventListener. When changing the value, you can use FCM to send push notifications using the http protocol. I use this in my application and it is very possible and reliable.
Note. . If you use this thread for an Android application, then using the sdk java server will be useful, since it is almost similar to what you have on android.
EDIT:. After I found out about this answer, I decided to share additional information with you.
// example node.js server as shown on this official firebase blog
var firebase = require('firebase'); var request = require('request'); var API_KEY = "..."; // Your Firebase Cloud Server API key firebase.initializeApp({ serviceAccount: ".json", databaseURL: "https://.firebaseio.com/" }); ref = firebase.database().ref(); function listenForNotificationRequests() { var requests = ref.child('notificationRequests'); ref.on('child_added', function(requestSnapshot) { var request = requestSnapshot.val(); sendNotificationToUser( request.username, request.message, function() { request.ref().remove(); } ); }, function(error) { console.error(error); }); }; function sendNotificationToUser(username, message, onSuccess) { request({ url: 'https://fcm.googleapis.com/fcm/send', 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 { onSuccess(); } }); } // start listening listenForNotificationRequests();
// sample Java test servlet I did to demonstrate this use case
@WebServlet("/TestServlet") public class MainServlet extends HttpServlet { * @see HttpServlet#HttpServlet() */ public MainServlet() { super(); } /** * @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)) .setDatabaseUrl(FIREBASE_DATABSE_URL).build(); // 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 FirebaseApp.initializeApp(options); 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))) { fcmHelper.setPreviousid(uniqueID); //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) { e.printStackTrace(); } // Setup http entity with json data and 'Content-Type' header StringEntity requestEntity = new StringEntity(outerBaseJsonObj.toString(), ContentType.APPLICATION_JSON); // Setup required Authorization header post.setHeader(AUTHORIZATION, FIREBASE_SERVER_KEY); // Pass setup entity to post request here post.setEntity(requestEntity); // 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) { result.append(line); } if (response != null) { // Print out the response to webpage PrintWriter out; out = response.getWriter(); out.println(result); System.out.println("This is Result - " + result); } } else { //Abort this process if conditions not met post.abort(); System.out.println(THIS_MSG_ALREADY_SENT); } } } /* * 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() { @Override public void onDataChange(DataSnapshot arg0) { // Clear idLastMessagerecivedhash map if not null if (lastMsgIdTreeMap != null) { lastMsgIdTreeMap.clear(); } //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 fcmHelper.setFcmTagId(sentBy); //Check if lstmsg is not null if (lstmsg != null) { // Create lastmsgTimestampHashMap here lastMsgIdTreeMap.put(sendToID, lstmsg); } //Check for null again if (lastMsgIdTreeMap != null) { chatLogs.setLastMsgIdTreeMap(lastMsgIdTreeMap); } try { doPost(request, response); } catch (ServletException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } @Override 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 messageRef.addValueEventListener(lastMsgListener); }
"The Java servlet is just a personal test. Some parts have been edited or deleted to give an idea of ββthis setting, it is in no way a ready-made servlet, please do not just copy and paste. I encourage you to understand and create your own. "