Firebase有新条目时如何向客户推送通知? [英] How to push notification to client when Firebase has a new entry?

查看:486
本文介绍了Firebase有新条目时如何向客户推送通知?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道,只要Firebase在特定的实体上添加新的子项,是否可以向Android移动设备发送推送通知。
例如,假设Firebase上有一个名为任务的实体。无论何时将新任务添加到该Firebase集合,child_added事件被触发,然后以某种方式将推送通知发送给移动客户端。
触发器是child_added事件。不过,我不确定从Firebase事件发送推送通知是否可行。 您可以制作一个非常简单的节点.js服务器或者一个java servlet(根据你的语言偏好)然后使用firebase服务器sdk你可以添加childEventListener。当值更改时,您可以使用FCM使用http协议发送推送通知。我在我的应用程序中使用这是非常可行和可靠的。注意:如果你正在使用这个流程的android应用程序,那么使用java服务器sdk将是有益的,因为它几乎类似于你有在Android上。



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



//示例node.js服务器在这个官方firebase博客
$ b

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

var API_KEY =...; //您的Firebase Cloud Server API密钥

firebase.initializeApp({
serviceAccount:.json,
databaseURL:https://.firebaseio.com/
});
ref = firebase.database()。ref();

函数listenForNotificationRequests(){
var requests = ref.child('notificationRequests');
ref.on('child_added',function(requestSnapshot){
var request = requestSnapshot.val();
sendNotificationToUser(
request.username,
request。
函数(){
request.ref()。remove();
}
);
},函数(错误){
console.error(error);
});
};

函数sendNotificationToUser(用户名,消息,onSuccess){
请求({
url:'https://fcm.googleapis.com/fcm/send',
方法:'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();
}
});
}

//开始监听
listenForNotificationRequests();

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

pre $ code $ @ $ $
public class MainServlet extends HttpServlet
@seeServlet(/ TestServlet HttpServlet#HttpServlet()
* /
public MainServlet(){
super();


$ ** b $ b * @请参阅HttpServlet#doGet(HttpServletRequest请求,HttpServletResponse
*响应)
* /
保护无效doGet(HttpServletRequest请求,HttpServletResponse响应)
抛出ServletException,IOException {

//获取上下文,然后从
获取保存的json配置文件的相对路径// firebase
ServletContext context = getServletContext();
String fullPath = context.getRealPath(FILE_PATH_FOR_JSON_SERVER_AUTH);


//检查是否从上面的路径获得了一个文件
if(fullPath!= null){

} else {



//在此设置连接到firebase数据库
FirebaseOptions选项=新的FirebaseOptions.Builder()。setServiceAccount(new FileInputStream(fullPath))
.setDatabaseUrl (FIREBASE_DATABSE_URL).build();


//检查以确保每次网页
//刷新时都不会初始化firebase应用程序
if(!exists){

//如果firebase应用程序不存在,则在此初始化并设置
// exists为true
FirebaseApp.initializeApp(options);
exists = true;





$ b //调用此函数开始在firebase数据库中侦听* notify *节点以获取通知
addNotificationListener (请求,响应);



$ **
查看HttpServlet#doPost(HttpServletRequest请求,HttpServletResponse
*响应)
* /
保护无效doPost(HttpServletRequest请求,HttpServletResponse响应)
抛出ServletException,IOException {

//建立apache httpclient POST请求
HttpClient客户端= HttpClientBuilder.create ()。建立();
HttpPost post = new HttpPost(ENDPOINT_URL);


//获取存储在lastMsgId树形图中的所需ID
if(!(chatLogs.getLastMsgIdTreeMap()。isEmpty())){


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

//设置一个唯一的id,连接sendToID和lstmsg
uniqueID = sendToID + lstmsg;
//设置一个以前的ID来检查唯一的ID。避免即时重复通知
previousID = fcmHelper.getPreviousid();

//检查uniqueId和PreviousID之前发送
if(!(uniqueID.equals(previousID))){
fcmHelper.setPreviousid(uniqueID);

//检查设备标记和用户标识hashmap是否为空
if(!(userLogs.getUserIdAndFcmTokenHashMap()。isEmpty())){

/ /在这里获取sendTo Id的设备标记
deviceToken = userLogs.getUserIdAndFcmTokenHashMap()。get(sendToID);

//为下游数据/通知创建JSON对象
JSONObject mainNotificationJsonObj = new JSONObject();
JSONObject outerBaseJsonObj = new JSONObject();
try {

//通知有效载荷有'title'和'body'键
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());

//这将用于通知或数据有效负载的情况
outerBaseJsonObj.put(TO,deviceToken);


//设置通知的优先级。对于即时聊天设置
// high将
//将设备从空闲状态唤醒 - 高电量耗尽
outerBaseJsonObj.put(PRIORITY_KEY,PRIORITY_HIGH);

//在此处指定所需的有效负载密钥,即'data'或
//'notification'。我们甚至可以在单个
//消息
中使用两个有效载荷outerBaseJsonObj.put(NOTIFICATION,mainNotificationJsonObj);
} catch(JSONException e){

e.printStackTrace();


$ b $ //用json数据和Content-Type头设置http实体
StringEntity requestEntity = new StringEntity(outerBaseJsonObj.toString(),
ContentType.APPLICATION_JSON);

//需要安装授权标题
post.setHeader(AUTHORIZATION,FIREBASE_SERVER_KEY);

//传递设置实体在这里发布请求
post.setEntity(requestEntity);

//执行apache http客户端post响应
HttpResponse fcmResponse = client.execute(post);


//从FCM服务器获取状态码以调试错误并成功
System.out.println(RESPONSE_CODE + fcmResponse.getStatusLine()。getStatusCode());

//从FCM服务器获取响应实体并读取行数
BufferedReader rd = new BufferedReader(new InputStreamReader(fcmResponse.getEntity()。getContent()));

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


if(response!= null){

//打印出对网页
的回复PrintWriter out;
out = response.getWriter();
out.println(result);
System.out.println(This is Result - + result);

} else {
//如果条件不符合,中止这个过程
post.abort();
System.out.println(THIS_MSG_ALREADY_SENT);
}

}

}





/ *
*这是在服务器启动时设置通知侦听器的主要方法
* /
$ b $ private void addNotificationListener(HttpServletRequest请求,HttpServletResponse响应){


//初始化值事件监听器
lastMsgListener = new ValueEventListener(){
$ b $ @Override
public void onDataChange(DataSnapshot arg0){

//清除idLastMessagerecivedhash映射如果不为空
if(lastMsgIdTreeMap!= null){
lastMsgIdTreeMap.clear();



$ b //获取lastmsg作为通知发送
lstmsg =(String)arg0.child(LAST_MESSAGE).getValue() ;

//在此获取sendToID
字符串sendToID =(字符串)arg0.child(SEND_TO).getValue();

//通过ID发送
sentBy =(String)arg0.child(SENT_BY).getValue();

//在这里设置fcmTag ID
fcmHelper.setFcmTagId(sentBy);

//检查lstmsg是否为空
if(lstmsg!= null){

//在这里创建lastmsgTimestampHashMap
lastMsgIdTreeMap.put(sendToID ,lstmsg);



$ b //再检查一次
if(lastMsgIdTreeMap!= null){

chatLogs.setLastMsgIdTreeMap (lastMsgIdTreeMap);

}

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

e.printStackTrace();
} catch(IOException e){

e.printStackTrace();




@Override
public void onCancelled(DatabaseError arg0){

}
};

//设置数据库引用来通知节点$ b $ messageRef = FirebaseDatabase.getInstance()。getReference()。child(NOTIFY);

//将值监听器添加到数据库引用
messageRef.addValueEventListener(lastMsgListener);


$ b}

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


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

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

//example test java servlet which I made just 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);



        }

"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."

这篇关于Firebase有新条目时如何向客户推送通知?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆