2

I have a function in an Android app which sends a POST request to an HTTP triggered Cloud Function. Whenever I click the button once to send the message, Firebase registers the event twice on the Firebase console. My application is built in such a way that the button to send a message disappears after the first click, so I'm not accidentally double clicking the button, and when I step through the debugger, the function to send the POST request is only called once. Can you guys help me? I don't know much about Firebase and can't find good documentation or other questions like this.

Here's the method which sends a message to my FCM cloud function:

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

My JavaScript takes the HTTP request, cuts it up and send the message to a topic which contains the other user's id (I did mean to do this verses sending to a specific device). Here's the JavaScript for my Cloud Function:

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

Finally, here are the logs: firebase console logs Which say that the function was called twice.

I've tried many links for answers such as the standard, https://firebase.google.com/docs/functions/http-events

and many StackOverflow posts. I haven't seen anyone else with the same problem.

Let Me Tink About It
  • 11,866
  • 13
  • 72
  • 169
  • 1
    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 https://firebase.google.com/docs/functions/http-events – mohamad rabee Aug 17 '17 at 17:18
  • 1
    @mohamadrabee That totally worked! Thank you so much. I'll repost your answer as an answer for anyone in the future – Bobby Puckett Aug 17 '17 at 17:43

1 Answers1

3

From @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 "

I added:

response.end();

after:

admin.messaging().sendToTopic(topicId, payload, options);

EDIT: After inserting this code, I still get the problem roughly 7% of the time. I had to change response.end(); to:

if (response.status(200)) {
    response.status(200).end(); 
} else {
    response.end();
}

I haven't had any problems since.