我正在尝试在iOS上的反应本机应用程序中实现通知,但我遇到了一个奇怪的问题。该应用程序能够显示本地通知,并显示来自 firebase 的远程通知,但它不会按预期触发反应原生推送通知的"onNotification"事件。我已经通过许多论坛寻找解决方案,但我仍然没有找到解决方案,这就是我请求您帮助的原因。
经过调查,我意识到objective-c函数"didReceiveLocalNotification"和"didReceiveRemoteNotification"从未被触发,所以我认为这是"onNotification"也没有触发的原因。不幸的是,我是这种语言的初学者,所以我无法理解问题的原因。
查看"didReceiveLocalNotification"文档,我读到这个函数已被弃用,我应该使用"willPresentNotification"代替,但像其他函数一样,它从未被触发。
作为记录,我遵循本指南来处理iOS中的通知: https://firebase.google.com/docs/cloud-messaging/ios/client。我正在 iOS 13、react-native 0.60.5、push-notifiaction-ios ^1.0.2、react-native-push-notification ^3.1.3 和 react-native-firebase ^5.5.6 上进行测试。
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if ([FIRApp defaultApp] == nil) {
[FIRApp configure];
[FIRMessaging messaging].delegate = self;
}
if ([UNUserNotificationCenter class] != nil) {
// iOS 10 or later
// For iOS 10 display notification (sent via APNS)
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert |
UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
[[UNUserNotificationCenter currentNotificationCenter]
requestAuthorizationWithOptions:authOptions
completionHandler:^(BOOL granted, NSError * _Nullable error) {
// ...
}];
} else {
// iOS 10 notifications aren't available; fall back to iOS 8-9 notifications.
UIUserNotificationType allNotificationTypes =
(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
UIUserNotificationSettings *settings =
[UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil];
[application registerUserNotificationSettings:settings];
}
[application registerForRemoteNotifications];
// Load RootView ...
return YES;
}
// sourceURLForBridge function ...
// Required to register for notifications
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
[RNCPushNotificationIOS didRegisterUserNotificationSettings:notificationSettings];
}
// Required for the register event.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
[RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
// Required for the notification event. You must call the completion handler after handling the remote notification.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
// Never called
[RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
// Required for the registrationError event.
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
[RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error];
}
// Required for the localNotification event.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
// Never called
[RNCPushNotificationIOS didReceiveLocalNotification:notification];
}
//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
// Never called
completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
//completionHandler(UNNotificationPresentationOptionAlert);
}
推送通知和火力基础配置
function configurePushNotification(){
PushNotification.configure({
onRegister: function(token) {
console.warn("TOKEN:", token);
},
onNotification: function(notification) {
console.warn("NOTIFICATION:", notification);
// Never called
notification.finish(PushNotificationIOS.FetchResult.NoData);
},
permissions: {
alert: true,
badge: true,
sound: true
},
popInitialNotification: true,
requestPermissions: true
});
}
async function checkPermission(onReady) {
const enabled = await firebase.messaging().hasPermission();
if (enabled) {
console.warn('checkPermission enabled');
getToken(onReady);
} else {
console.warn('checkPermission disabled');
requestPermission(onReady);
}
}
async function requestPermission(onReady) {
try {
await firebase.messaging().requestPermission();
// User has authorised
console.warn('requestPermission try');
getToken(onReady);
} catch (error) {
// User has rejected permissions
console.error(error)
console.warn('requestPermission rejected');
}
}
async function getToken(onReady) {
fcmToken = await AsyncStorage.getItem('fcmToken');
if (!fcmToken) {
fcmToken = await firebase.messaging().getToken();
if (fcmToken) {
// user has a device token
await AsyncStorage.setItem('fcmToken', fcmToken);
}
}
console.warn(fcmToken)
if(onReady) onReady()
}
class App extends React.Component {
async componentDidMount() {
checkPermission()
configurePushNotification()
}
render(){
return (
// View ...
)
}
};
感谢您的帮助!
编辑:经过调查,我意识到这些事件在我将Firebase/Messaging 添加到我的pod文件后停止工作。但根据Firebase文件,这不是正常行为。知道这是什么原因吗?
我有办法做到这一点。
我没有弄清楚为什么这些事件没有在AppDelegate.m中调用,但我注意到Firebase消息传递实现的相同事件(转到Pods/Development Pods/RNFirebase/消息传递和通知中的代码(在通知出现时被调用。所以我假设这段代码覆盖了我在 AppDelegate.m 中的代码。
事实上,我没有听好的Javascript事件。此处指定的事件 https://rnfirebase.io/docs/v5.x.x/messaging/receiving-messages 和此处指定的事件 https://rnfirebase.io/docs/v5.x.x/notifications/receiving-notifications iOS 中为我工作。但是这些事件不是在安卓上调用的...
因此,我结束了在Android和iOS上以不同的方式处理通知,使用:
-
适用于 Android 的 react-native-push-notification 的 "onNotification">
-
"onNotification"和"onNotificationOpened"的react-native-firebase for iOS。
本地通知由设备发送。
远程通知 (APNS( 由您的服务器发送,由 Apple 服务器传递。 您向 Apple 发送通知,如果允许,Apple 会向设备发送通知。
如果您使用的是Firebase等服务,则向Firebase发送通知,Firebase向Apple发送通知,Apple向用户发送通知。
Firebase 云消息传递在 ObjC 中使用方法重排,如文档中所述。所以,onNotification
不叫。
我建议将此组件用于 React Native。源代码中有一个示例应用,其中包含已配置的AppDelegate.m
。