Firebase有新条目时如何向客户推送通知? [英] How to push notification to client when Firebase has a new entry?
问题描述
例如,假设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屋!