为什么使用 Android HTTP 请求触发器多次调用此 Cloud Functions?
Why is this Cloud Function called more than once with an Android HTTP request trigger?
我在 Android 应用程序中有一个函数,它向 HTTP 触发的云函数发送 POST 请求。每当我单击一次按钮发送消息时,Firebase 都会在 Firebase 控制台上注册该事件两次。我的应用程序的构建方式是第一次单击后发送消息的按钮会消失,所以我不会不小心双击按钮,当我单步执行调试器时,发送 POST 的函数请求只被调用一次。你们能帮帮我吗?我对 Firebase 了解不多,找不到好的文档或其他类似的问题。
这是向我的 FCM 云函数发送消息的方法:
public void sendPushToSingleInstance(final Context activity, final String message, final String myId, final String theirId) {
final String url = URL_TO_CLOUD_FUNCTION;
StringRequest myReq = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Toast.makeText(activity, "Success", Toast.LENGTH_SHORT).show();
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
if (error.networkResponse != null)
Toast.makeText(activity, String.valueOf(error.networkResponse.statusCode), Toast.LENGTH_SHORT).show();
else
Toast.makeText(activity, "some error", Toast.LENGTH_SHORT).show();
}
}) {
@Override
public byte[] getBody() throws com.android.volley.AuthFailureError {
Map<String, String> rawParameters = new Hashtable<String, String>();
//not used
return new JSONObject(rawParameters).toString().getBytes();
};
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("from", myId);
headers.put("message", message);
headers.put("sendingTo", theirId);
return headers;
}
};
Volley.newRequestQueue(activity).add(myReq);
}
我的 JavaScript 接受 HTTP 请求,将其分解并将消息发送到包含其他用户 ID 的主题(我的意思是这样做而不是发送到特定设备)。
这是我的云函数的 JavaScript:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendMessage = functions.https.onRequest((request, response) => {
var topicId = request.get('sendingTo');
var color = request.get('color');
var from = request.get('from')
console.log('tried to push notification');
const payload = {
notification: {
title: from,
body: color,
sound: "default"
},
};
const options = {
priority: "high",
timeToLive: 60 * 60 * 24
};
admin.messaging().sendToTopic(topicId, payload, options);
});
最后,这是日志:
firebase console logs
其中说该函数被调用了两次。
我尝试了很多链接来获取答案,例如标准、
https://firebase.google.com/docs/functions/http-events
和许多 Whosebug 帖子。我还没有看到其他人有同样的问题。
来自@mohamadrabee,"this from the documentation 'Always end an HTTP function with send(), redirect(), or end(). Otherwise, your function might to continue to run and be forcibly terminated by the system.' see firebase.google.com/docs/functions/http-events "
我补充了:
response.end();
之后:
admin.messaging().sendToTopic(topicId, payload, options);
编辑:插入这段代码后,我仍然有大约 7% 的时间遇到问题。我不得不将 response.end();
更改为:
if (response.status(200)) {
response.status(200).end();
} else {
response.end();
}
从那以后我没有遇到任何问题。
我在 Android 应用程序中有一个函数,它向 HTTP 触发的云函数发送 POST 请求。每当我单击一次按钮发送消息时,Firebase 都会在 Firebase 控制台上注册该事件两次。我的应用程序的构建方式是第一次单击后发送消息的按钮会消失,所以我不会不小心双击按钮,当我单步执行调试器时,发送 POST 的函数请求只被调用一次。你们能帮帮我吗?我对 Firebase 了解不多,找不到好的文档或其他类似的问题。
这是向我的 FCM 云函数发送消息的方法:
public void sendPushToSingleInstance(final Context activity, final String message, final String myId, final String theirId) {
final String url = URL_TO_CLOUD_FUNCTION;
StringRequest myReq = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Toast.makeText(activity, "Success", Toast.LENGTH_SHORT).show();
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
if (error.networkResponse != null)
Toast.makeText(activity, String.valueOf(error.networkResponse.statusCode), Toast.LENGTH_SHORT).show();
else
Toast.makeText(activity, "some error", Toast.LENGTH_SHORT).show();
}
}) {
@Override
public byte[] getBody() throws com.android.volley.AuthFailureError {
Map<String, String> rawParameters = new Hashtable<String, String>();
//not used
return new JSONObject(rawParameters).toString().getBytes();
};
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("from", myId);
headers.put("message", message);
headers.put("sendingTo", theirId);
return headers;
}
};
Volley.newRequestQueue(activity).add(myReq);
}
我的 JavaScript 接受 HTTP 请求,将其分解并将消息发送到包含其他用户 ID 的主题(我的意思是这样做而不是发送到特定设备)。 这是我的云函数的 JavaScript:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendMessage = functions.https.onRequest((request, response) => {
var topicId = request.get('sendingTo');
var color = request.get('color');
var from = request.get('from')
console.log('tried to push notification');
const payload = {
notification: {
title: from,
body: color,
sound: "default"
},
};
const options = {
priority: "high",
timeToLive: 60 * 60 * 24
};
admin.messaging().sendToTopic(topicId, payload, options);
});
最后,这是日志: firebase console logs 其中说该函数被调用了两次。
我尝试了很多链接来获取答案,例如标准、 https://firebase.google.com/docs/functions/http-events
和许多 Whosebug 帖子。我还没有看到其他人有同样的问题。
来自@mohamadrabee,"this from the documentation 'Always end an HTTP function with send(), redirect(), or end(). Otherwise, your function might to continue to run and be forcibly terminated by the system.' see firebase.google.com/docs/functions/http-events "
我补充了:
response.end();
之后:
admin.messaging().sendToTopic(topicId, payload, options);
编辑:插入这段代码后,我仍然有大约 7% 的时间遇到问题。我不得不将 response.end();
更改为:
if (response.status(200)) {
response.status(200).end();
} else {
response.end();
}
从那以后我没有遇到任何问题。