React Native + Firebase Cloud Messaging - 获取令牌导致服务工作者错误
我一直在尝试在我的 React Native 应用上配置和设置 Firebase Cloud Messaging,因为我希望我的项目具有点对点推送通知。我想将其发布到 Android,并最终发布到 iOS,但我一直在 Web 视图 (http://localhost:19006) 中测试它。该项目采用 TypeScript 编写,并使用 Stack.Router 和 Expo
./App.tsx
...
import FIREBASE from './src/http/firebase/interface';
...
export default function App() {
React.useEffect(async () => {
return await FIREBASE.init()
});
return (
<SafeAreaProvider>
<GlobalContextProvider>
<Navigation colorScheme={colorScheme} />
<StatusBar />
</GlobalContextProvider>
</SafeAreaProvider>
);
}
./src/http/firebase
...
// EXPO INSTALL FIREBASE
import { initializeApp } from 'firebase/app';
import { getMessaging, getToken } from 'firebase/messaging';
import {
FIREBASE_API_KEY,
FIREBASE_AUTH_DOMAIN,
FIREBASE_DATABASE_URL,
FIREBASE_PROJECT_ID,
FIREBASE_STORAGE_BUCKET,
FIREBASE_MESSAGING_SENDER_ID,
FIREBASE_APP_ID,
FIREBASE_WEB_VAPID_KEY,
// @ts-ignore
} from '@env';
const firebaseConfig = {
apiKey: FIREBASE_API_KEY,
authDomain: FIREBASE_AUTH_DOMAIN,
databaseURL: FIREBASE_DATABASE_URL,
projectId: FIREBASE_PROJECT_ID,
storageBucket: FIREBASE_STORAGE_BUCKET,
messagingSenderId: FIREBASE_MESSAGING_SENDER_ID,
appId: FIREBASE_APP_ID,
};
// @ts-ignore
let firebase;
// @ts-ignore
let messaging;
if (!firebase) {
firebase = initializeApp(firebaseConfig);
console.log(firebase);
}
const init = async () => {
// const registrations = await navigator.serviceWorker.getRegistrations();
// if (registrations.length === 0) {
// const registration = await navigator.serviceWorker.register('./firebase-messaging-sw.js');
// console.log(registration)
// }
// @ts-ignore
messaging = await getMessaging(firebase);
console.log(messaging);
switch(Platform.OS) {
// case 'android':
// Do Nothing, as of now.
case 'web':
// @ts-ignore
if (messaging) {
try {
// @ts-ignore
const token = await getToken(messaging, { vapidKey: FIREBASE_WEB_VAPID_KEY })
if (token) {
console.log(token);
}
} catch(err) {
// TODO err handling
console.log(err)
}
}
// init app config
break;
case 'ios':
break;
}
};
const FIREBASE = {
init,
firebase,
messaging,
};
export default FIREBASE;
版本:
"react-native": "0.64.3",
"react-native-firebase": "5.6",
"firebase": "^9.6.11",
"@react-native-firebase/app": "^14.8.0",
"@react-native-firebase/messaging": "^14.8.0", // Multiple versions of Firebase packages since I was struggling, and followed a handful of different guides.
我已按照指南将常见依赖项添加到 ./android/build.gradle 和 ./android/app/build.gradle
firebase
和
messaging
的两个日志按预期生成
FirebaseAppImpl
对象和
MessagingService
对象。
在加载应用程序的 Web 实例(
expo start
并选择 web)时,我遇到了此错误:
FirebaseError: Messaging: We are unable to register the default service worker. Failed to register a ServiceWorker for scope ('http://localhost:19006/firebase-cloud-messaging-push-scope') with script ('http://localhost:19006/firebase-messaging-sw.js'): The script has an unsupported MIME type ('text/html').
我
已
将
firebase-messaging-sw.js
文件放在我的根文件夹和我的 web-build 文件夹中,因为我无权访问单个 /build 文件夹。
尝试在 Android 模拟器(Android Studio、Pixel XL API 30、Android 11.0 w/ Google API,否则为默认设置)中加载应用程序时,我收到以下错误:
[Unhandled promise rejection: TypeError: undefined is not an object (evaluating 'navigator.serviceWorker.addEventListener')]
[Unhandled promise rejection: FirebaseError: Messaging: This browser doesn't support the API's required to use the Firebase SDK. (messaging/unsupported-browser).]
我很感激任何见解或帮助。到目前为止,我觉得我已经浏览了数百篇关于 Firebase 和 React Native 的论坛帖子。
firebase 消息传递仅支持 localhost 和 HTTPS 主机
下面是我的
@/plugin/firebase.js
import { initializeApp } from 'firebase/app'
import { getMessaging, onMessage, isSupported } from 'firebase/messaging'
const firebaseConfig = {
...
}
const app = initializeApp(firebaseConfig)
let messaging = null
isSupported().then((result) => {
if (result) {
const messaging = getMessaging(app)
onMessage(messaging, (payload) => {
const options = {
body: payload.notification.body,
icon: '/img/icons/android-chrome-192x192.png',
click_action: payload.data.click_action || '/some/path/for/click/action',
}
navigator.serviceWorker.getRegistration().then((reg) => {
reg.showNotification(payload.notification.title, options)
})
})
}
})
export default messaging
和
firebase-messaging-sw.js
importScripts('https://www.gstatic.com/firebasejs/9.6.11/firebase-app-compat.js')
importScripts('https://www.gstatic.com/firebasejs/9.6.11/firebase-messaging-compat.js')
const firebaseConfig = {
...
}
firebase.initializeApp(firebaseConfig)
let messaging = null
if (firebase.messaging.isSupported()) {
const messaging = firebase.messaging()
messaging.onBackgroundMessage(function (payload) {
console.log('[firebase-messaging-sw.js] Received background message ', payload)
const options = {
body: payload.notification.body,
icon: '/img/icons/android-chrome-192x192.png',
click_action: payload.data.click_action || '/some/path/for/click/action',
}
return self.registration.showNotification(payload.notification.title, options)
})
}
的代码片段>
希望这些对您有所帮助 :)
已修复:
React Native Expo 项目,
添加
web/
目录,将
firebase-messaging-sw.js
放入其中,然后运行 ​​
expo build:web
以便在构建的 index.html 中正确引用 firebase sw 文件。