Firebase云消息推送在Vue中的前台通知无法工作

8

我一直在努力将FCM集成到我的Vue PWA应用程序中。到目前为止,我已经成功地使后台通知工作,但是在应用程序前台处理通知的功能不起作用。以下是我的代码。

src/App.vue

import firebase from './plugins/firebase'

export default {
  // Other stuff here...

  methods: {
    prepareFcm () {
      var messaging = firebase.messaging()
      messaging.usePublicVapidKey(this.$store.state.fcm.vapidKey)
      messaging.getToken().then(async fcmToken => {
        this.$store.commit('fcm/setToken', fcmToken)
        messaging.onMessage(payload => {
          window.alert(payload)
        })
      }).catch(e => {
        this.$store.commit('toast/setError', 'An error occured to push notification.')
      })
    }
  },

  mounted () {
    this.prepareFcm()
  }
}

public/firebase-messaging-sw.js

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

firebase.initializeApp({
  messagingSenderId: '123456789'
})

const messaging = firebase.messaging()

messaging.setBackgroundMessageHandler(function (payload) {
  return self.registration.showNotification(payload)
})

src/plugins/firebase.js

import firebase from '@firebase/app'
import '@firebase/messaging'
// import other firebase stuff...

const firebaseConfig = {
  apiKey: '...',
  authDomain: '...',
  databaseURL: '...',
  projectId: '...',
  storageBucket: '...',
  messagingSenderId: '123456789',
  appId: '...'
}

firebase.initializeApp(firebaseConfig)

export default firebase

我哪里做错了?

你尝试过将 "messaging.onMessage(payload => {window.alert(payload)})" 这个 onMessage 块移出函数,在成功获取 FCM 令牌后吗?我认为这个 onMessage 函数不需要放在获取 FCM 令牌的 promise 中。 - Jake Lam
我遇到了同样的问题,请告诉我如果你解决了它。 - MaBbKhawaja
4个回答

2

我在StackOverflow上的另一个问答中找到了解决方案(但我无法找到它的原因)。

事实证明,您必须使用Firebase API v7.8.0而不是文档中当时所说的5.5.6。 因此,public/firebase-messaging-sw.js中的前两行应改为以下内容:

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

如果有人能找到那个QA,请随意编辑我的答案以包含该链接。 - starleaf1

2

我遇到了同样的问题。在我的情况下,"package.json""firebase-messaging-sw.js"中的firebase版本不同。在"firebase-messaging-sw.js"中设置与"package.json"中相同的importScripts版本后,我的问题得到了解决。

更改之前

 **"package.json"**
 
 "firebase": "^8.2.1",
 
  **"firebase-messaging-sw.js"**

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

更改后

 **"package.json"**

 "firebase": "^8.2.1",

 **"firebase-messaging-sw.js"**

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

0

我在使用Vue 3(配合Vite)设置Firebase推送通知时遇到了很多问题,而且我启用了vite-plugin-pwa的PWA支持,所以有时候感觉像是盲目操作。最终我成功设置了PWA支持,但接着又遇到了以下问题:

  • 当我的应用程序没有焦点时,我可以在后台收到通知,但在前台却不能。
  • 当我在后台收到通知时,它会出现两次。

这是我的完整设置。截至本帖发布,我使用的是最新的Firebase版本(9.12.1)。

// firebase-messaging-sw.js file in the public folder
   
importScripts(
      "https://www.gstatic.com/firebasejs/9.12.1/firebase-app-compat.js"
    );
importScripts(
      "https://www.gstatic.com/firebasejs/9.12.1/firebase-messaging-compat.js"
    );
// Initialize Firebase
firebase.initializeApp({
  apiKey: "",
  authDomain: "",
  projectId: "",
  storageBucket: "",
  messagingSenderId: "",
  appId: "",
  measurementId: "",
});
const messaging = firebase.messaging();

    
messaging.onBackgroundMessage(function (payload) {
// Customize notification here
  const notificationTitle = payload.notification.title;
  const notificationOptions = {
  body: payload.notification.body,
  icon: "/icon.png",
};

self.registration.showNotification(notificationTitle, notificationOptions);
});

我在网上看到一些帖子提供了服务工作者中的onBackgroundMessage,但是我尝试将其注释掉后,通知出现两次的问题似乎得到了解决。

接下来,有一个firebase.js文件,我从中检索令牌,并随后监听前台通知。

// firebase.js in same location with main.js
    
import firebase from "firebase/compat/app";
import { getMessaging } from "firebase/messaging";
    
const firebaseConfig = {
  apiKey: "",
  authDomain: "",
  projectId: "",
  storageBucket: "",
  messagingSenderId: "",
  appId: "",
  measurementId: "",
};
    
const app = firebase.initializeApp(firebaseConfig);
export default getMessaging(app);

然后在 main.js

import App from "./App.vue";
import firebaseMessaging from "./firebase";

const app = createApp(App)
app.config.globalProperties.$messaging = firebaseMessaging; //register as a global property

最后,在App.vue中(或者你希望获取令牌并发送到服务器端的任何地方)...
import {getToken, onMessage} from "firebase/messaging";

export default {
  mounted() {
    getToken(this.$messaging, {
      vapidKey:
        "XXX-XXX",
    })
      .then((currentToken) => {
        if (currentToken) {
          console.log("client token", currentToken);
          onMessage(this.$messaging, (payload) => {
            console.log("Message received. ", payload);
          });
          
          //send token to server-side
        } else {
          console.log(
            "No registration token available. Request permission to generate one"
          );
        }
      })
      .catch((err) => {
        console.log("An error occurred while retrieving token.", err);
      });
  }
}

当然不要忘记vapidKey。花了一分钟,但它完美地工作了。

目前,我不提供任何关于前台通知应该长什么样的意见,所以我只是记录有效载荷。但请随意根据您的需要展示它。


0
在我的情況下,package.json 上的版本號(8.2.1)與實際的 SDK_VERSION(8.0.1)不同。
更改為相同版本的 service-workers 後,問題得到了解決。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接