在React Native 0.84.1上,Expo推送通知错误:默认的FirebaseApp尚未初始化
我正在开发一个使用Expo的 React Native应用(0.84.1),并尝试通过Firebase实现推送通知。
我严格按照Expo文档,特别是 “创建一个新的Google服务账户密钥。” 这部分。
然而,每次调用 getExpoPushTokenAsync() 时,我都会收到以下错误:
请确保完成指南在
https://docs.expo.dev/push-notifications/fcm-credentials/:
默认的FirebaseApp未在此进程中初始化
com.guilherme_naxe.naxemobile。
请确保先调用FirebaseApp.initializeApp(Context)。
正如我所提到的,我已经遵循文档中的所有要求。下面是我的代码和设置中的一些重要部分:
1. app.json
...
"android": {
...
"package": "com.teste123.naxemobile",
"googleServicesFile": "./google-services.json"
},
"ios": {
"supportsTablet": true,
"bundleIdentifier": "com.teste123.naxemobile"
}
...
2. push-notification-service.ts
import * as Device from 'expo-device';
import * as Notifications from 'expo-notifications';
import { Platform } from 'react-native';
import { httpRequest } from '../base-http/base-http';
import { SecureStorage } from '@/utils/storage/secure-storage';
import Constants from "expo-constants";
Notifications.setNotificationHandler({
handleNotification: async () => ({
shouldShowBanner: true,
shouldShowList: true,
shouldPlaySound: true,
shouldSetBadge: true,
})
});
export async function registerForPushNotifications(): Promise<void> {
if (!Device.isDevice) return;
const { status: existingStatus } = await Notifications.getPermissionsAsync();
let finalStatus = existingStatus;
if (existingStatus !== 'granted') {
const { status } = await Notifications.requestPermissionsAsync();
finalStatus = status;
}
if (finalStatus !== 'granted') return;
console.log('Permissions status:', finalStatus);
if (Platform.OS === 'android') {
console.log('Setting Android notification channel...');
await Notifications.setNotificationChannelAsync('vendas', {
name: 'Vendas',
importance: Notifications.AndroidImportance.MAX,
vibrationPattern: [0, 250, 250, 250],
sound: 'default',
});
}
console.log('Getting push token...');
const token = await Notifications.getExpoPushTokenAsync({
projectId: Constants.expoConfig?.extra?.eas.projectId,
});
console.log('Push token received:', token);
const authToken = await SecureStorage.getAuthToken();
if (!authToken) return;
await httpRequest('/Client/User/PushToken', {
method: 'POST',
body: { pushToken: token },
headers: { Authorization: `Bearer ${authToken}` },
});
}
其他细节
- 我把
google-services.json文件放在/android/app里面。 - 我在Expo项目设置中上传了 FCM V1服务账户密钥。
- 我直接在终端用Gradle构建了APK。
- 我的项目中没有任何手动Firebase初始化代码。
- 我对所有Firebase项目ID和凭据进行了再次核对。
我还尝试过:
- 将
googleServicesFile改为./android/app/google-services.json - 将
google-services.json放在项目根目录并在app.json中指向它 - 删除并重新生成
android文件夹 - 我找到了一个Reddit讨论串,声称解决了这个问题。
- 我也跟着一个YouTube教程。
尽管如此,我仍然遇到同样的错误。
有没有人遇到过这个问题,或者知道如何修复?
如果需要更多细节,请告诉我。
解决方案
好吧,经过多小时的查找,我所需要做的不过是
- 按如下编辑我的
push-notification-service.ts:
``` import { useState, useEffect, useRef } from 'react'; import { Text, View, Button, Platform } from 'react-native'; import * as Device from 'expo-device'; import * as Notifications from 'expo-notifications'; import Constants from 'expo-constants';
Notifications.setNotificationHandler({ handleNotification: async () => ({ shouldPlaySound: true, shouldSetBadge: true, shouldShowBanner: true, shouldShowList: true, }), });
function handleRegistrationError(errorMessage: string) { // alert(errorMessage); throw new Error(errorMessage); }
export async function registerForPushNotificationsAsync() { if (Platform.OS === 'android') { await Notifications.setNotificationChannelAsync('default', { name: 'default', importance: Notifications.AndroidImportance.MAX, vibrationPattern: [0, 250, 250, 250], lightColor: '#FF231F7C', }); }
if (Device.isDevice) {
const { status: existingStatus } = await Notifications.getPermissionsAsync();
let finalStatus = existingStatus;
if (existingStatus !== 'granted') {
const { status } = await Notifications.requestPermissionsAsync();
finalStatus = status;
}
if (finalStatus !== 'granted') {
handleRegistrationError('Permission not granted to get push token for push notification!');
return;
}
const projectId =
Constants?.expoConfig?.extra?.eas?.projectId ?? Constants?.easConfig?.projectId;
if (!projectId) {
handleRegistrationError('Project ID not found');
}
try {
const pushTokenString = (
await Notifications.getExpoPushTokenAsync({
projectId,
})
).data;
console.log(pushTokenString);
return pushTokenString;
} catch (e: unknown) {
handleRegistrationError(`${e}`);
}
} else {
handleRegistrationError('Must use physical device for push notifications');
}
}
``
2. 把我的google-services.json` 放在根文件夹,并像下面这样修改app.json:
"android": {
...
"package": "com.teste123.naxemobile",
"googleServicesFile": "./google-services.json"
},
"ios": {
"supportsTablet": true,
"bundleIdentifier": "com.teste123.naxemobile"
},
3.在终端运行 npx expo prebuild --clean 以重新创建我的android文件夹
4.运行 npx expo run:android --device 并开心