2

我在 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

和许多 StackOverflow 帖子。我还没有看到其他人有同样的问题。

4

1 回答 1

3

来自@mohamadrabee,“来自文档'始终使用 send()、redirect() 或 end() 结束 HTTP 函数。否则,您的函数可能会继续运行并被系统强制终止。” 请参阅 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();
}

从那以后我没有任何问题。

于 2017-08-17T17:51:41.937 回答