Почему эта облачная функция вызывается более одного раза с помощью триггера HTTP-запроса Android?

У меня есть функция в приложении для Android, которая отправляет запрос POST к облачной функции, запускаемой по протоколу HTTP. Каждый раз, когда я нажимаю кнопку один раз, чтобы отправить сообщение, 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-запрос, разрезает его и отправляет сообщение в тему, содержащую идентификатор другого пользователя (я действительно хотел сделать это, отправив стихи на определенное устройство). Вот 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, которые говорят, что функция была вызвана дважды.

Я перепробовал много ссылок для ответов, таких как стандартный, https://firebase.google.com/docs/functions/http-events

и много сообщений Stackru. Я не видел никого другого с такой же проблемой.

1 ответ

Решение

От @mohamadrabee, "это из документации". Всегда заканчивайте HTTP-функцию с помощью send(), redirect() или end(). В противном случае ваша функция может продолжать выполняться и принудительно завершаться системой.' см. 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();
}

У меня не было никаких проблем с тех пор.

Другие вопросы по тегам