当前位置: 首页 > 知识库问答 >
问题:

当Firebase有一个新条目时,如何向客户端推送通知?

曹兴贤
2023-03-14

我想知道是否可以在Firebase在特定实体上添加一个新的子实体时向android移动设备发送推送通知。例如,假设Firebase上有一个名为tasks的实体。每当一个新任务添加到firebase集合中时,就会触发“child_added”事件,然后以某种方式向移动客户端发送推送通知。触发器是child_added事件。但是,我不确定从Firebase事件发送推送通知是否可行。

共有1个答案

汪茂
2023-03-14

您可以创建一个非常简单的node.js服务器或java servlet(根据您的语言首选项),然后使用firebase server sdk,添加ChildEventListener。当值更改时,您可以使用FCM发送使用http协议的推送通知。我正在我的应用程序中使用这个,它是非常可行和可靠的。

注意:如果您将此流用于android应用程序,那么使用java server sdk将是有益的,因为它几乎与您在android上所拥有的类似。

编辑:在得到一些聚光灯对这个答案,我想分享一些更多的信息关于相同。

//在firebase官方博客上看到的node.js服务器示例

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();

//示例测试java servlet,我制作它只是为了演示这个用例

@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);



        }

“Java servlet只是一个个人测试。一些部分已经被编辑或删除,只是给出一个关于它的设置的想法,这绝不是生产就绪的servlet请不要只是复制粘贴。我鼓励您理解并构建自己的。”

 类似资料: