繁体   English   中英

Firebase 云消息前台通知在 Vue 中不起作用

[英]Firebase Cloud Messaging foreground notification not working in Vue

我一直致力于将 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

我做错了什么?

我在 StackOverflow 的另一个 QA 中找到了解决方案(由于某种原因我再也找不到了)。

事实证明你必须使用 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')

我遇到了同样的问题。 在我的例子中, “package.json”“firebase-messaging-sw.js” importScripts 版本中的 firebase 版本不同。 "package.json"中的 "firebase -messaging-sw.js" 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');

在我的例子中, package.json (8.2.1) 上的版本与实际的 SDK_VERSION (8.0.1) 不同

在更改了具有相同版本的服务人员后工作..

我在为 Vue 3(使用 Vite)设置 firebase 推送通知时遇到了很多问题,并且我使用vite-plugin-pwa启用了 PWA 支持,所以感觉我有一半时间都在盲目飞行。 我终于能够设置对 PWA 的支持,但后来我遇到了以下问题:

  • 我在后台收到通知(当我的应用程序不在焦点时),但不是在前台。
  • 当我确实在后台收到通知时,它出现了两次。

这是我的完整设置。 截至这篇文章( 9.12.1 ),我有最新的 firebase

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

我在网上看到一些帖子在 service worker 中提供了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 花了一分钟,但效果很好。

目前,对于前台通知应该是什么样子,我不提供任何意见,所以我只是记录有效负载。 但请随意展示它,但你认为合适。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM