我一直在尝试在我的React Native应用程序上配置和设置Firebase Cloud Messaging,因为我希望我的项目具有点对点推送通知。我想发布这个Android,最终iOS,但我一直在测试这个在web视图(http://localhost:19006)。这个项目是用TypeScript编写的,并且使用了Stack。Router and 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/重火力点
...
// 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
和select 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的论坛帖子。
仅在localhost上支持firebase消息传递和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文件。