Firebase cloud messaging onMessage not triggered in React app even after message is sent

╄→尐↘猪︶ㄣ 提交于 2020-02-24 14:59:21

问题


I am testing out the Firebase Cloud Messaging function in my React app which was bootstrapped with create-react-app. Note that I have already intialized firebase (including admin SDK on server-side) properly and my client side is deployed on https. What I did so far was to:

  1. Initialize firebase messaging in firebase.js, and also request for notification permission and listen out for onMessage event
const messaging = firebase.messaging();
messaging
  .requestPermission()
  .then(() => {
    console.log("Permission granted!");
  })
  .catch(() => {
    console.log("Permission denied!");
  });

messaging.onMessage(payload => {
  console.log("onMessage: ", payload);
});
  1. Create service worker file firebase-messaging-sw.js in public directory
importScripts("https://www.gstatic.com/firebasejs/4.8.1/firebase-app.js");
importScripts("https://www.gstatic.com/firebasejs/4.8.1/firebase-messaging.js");

var config = {
  messagingSenderId: <messageID hidden>
};
firebase.initializeApp(config);

const messaging = firebase.messaging();

  1. I read from another Stackoverflow post that with create-react-app post that this was also necessary to include in index.js
if ("serviceWorker" in navigator) {
  navigator.serviceWorker
    .register("../firebase-messaging-sw.js")
    .then(function(registration) {
      console.log("Registration successful, scope is:", registration.scope);
    })
    .catch(function(err) {
      console.log("Service worker registration failed, error:", err);
    });
}
  1. To test out the messaging easily, I added a button in Main.js that will send to my server the token on click (and then the server will proceed to send the message)
const handlePushButtonClick = () => {
    messaging.getToken().then(token => {
      axios.post(<Server link hidden>, {
        token
      });
    });
  };
  1. I then set up the necessary route in my express server like this
app.post("/api/push", async (req, res) => {
    const registrationToken = req.body.token;
    var message = {
      data: {
        score: "850",
        time: "2:45"
      },
      token: registrationToken
    };
    fb.admin
      .messaging()
      .send(message)
      .then(response => {
        console.log("Successfully sent message:", response);
        res.sendStatus(200);
      })
      .catch(error => {
        console.log("Error sending message:", error);
      });
  });

Here's the issue, I have verified that my server is successfully receiving the token and in fact has successfully sent the message but on my client-side, I am not receiving the onMessage payload object at all.

Recall from my code that what I expect to receive on my client side dev console is a console.log with onMessage and the payload.

messaging.onMessage(payload => {
  console.log("onMessage: ", payload);
});

回答1:


I have figured out my mistake. I was initially following this guide: https://firebase.google.com/docs/cloud-messaging/js/topic-messaging. My mistake was previously not very clear to me as I followed the tutorial, but that's probably because I am quite unfamiliar with the notifications and push web APIs.

The tutorial's message object had a data object inside it:

var message = {
  data: {
    score: '850',
    time: '2:45'
  },
  token: registrationToken
};

Turns out that if I wanted to send a data payload in the message, I needed to include this bunch of code in my firebase-messaging-sw.js (this bit wasn't shown in the tutorial I linked):

messaging.setBackgroundMessageHandler(payload => {
  const title = payload.data.title;
  const options = {
    body: payload.data.score
  };
  return self.registration.showNotification(title, options);
});

Note that the above code in the service worker file is only necessary if you want to send a data payload (which you can thereafter flexibly manipulate in the service worker file). If all you need is to send a notification, your message object should instead simply include a notification object (that can accept only some fixed keys):

var message = {
  notification: {
    title: '850',
    body: '2:45'
  },
  token: registrationToken
};



回答2:


Simple solution to this is update your Firebse to latest versions.

eg.

importScripts('https://www.gstatic.com/firebasejs/7.8.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/7.8.0/firebase-messaging.js');

Note: Once you have updated your firebase libraries versions then messagingSenderId will not work in your firebase-messaging-sw.js file. You have to provide all other params eg. apiKey, projectId, appId along with messagingSenderId.

Eg.

Replace this in your firebase-messaging-sw.js

firebase.initializeApp({
    messagingSenderId: "Sender ID"
});

With this

firebase.initializeApp({
        apiKey: "api-key",
        authDomain: "project-id.firebaseapp.com",
        databaseURL: "https://project-id.firebaseio.com",
        projectId: "project-id",
        storageBucket: "project-id.appspot.com",
        messagingSenderId: "sender-id",
        appId: "app-id",
});
  • If still not work. Clean your browser cache and re-register service worker.


来源:https://stackoverflow.com/questions/55559020/firebase-cloud-messaging-onmessage-not-triggered-in-react-app-even-after-message

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!