首页
学习
活动
专区
圈层
工具
发布

在React Native iOS中显示自定义FCM推送通知

React Native iOS中显示自定义FCM推送通知

基础概念

FCM (Firebase Cloud Messaging) 是Google提供的跨平台消息推送服务,允许开发者向iOS和Android设备发送通知和消息。在React Native应用中实现自定义FCM推送通知需要理解以下核心概念:

  1. 推送通知生命周期:从服务器发送到设备接收的完整流程
  2. 通知渠道 (iOS中称为通知类别):用于区分不同类型的通知
  3. 静默通知:不直接显示但可以触发应用逻辑的消息
  4. 前台/后台处理:应用在不同状态下的通知处理方式

实现方案

1. 安装必要依赖

代码语言:txt
复制
yarn add @react-native-firebase/app @react-native-firebase/messaging
cd ios && pod install

2. iOS配置

a. 在Xcode中配置推送通知能力

  1. 打开项目ios/YourAppName.xcworkspace
  2. 选择主target -> Signing & Capabilities
  3. 添加"Push Notifications"和"Background Modes"能力
  4. 在Background Modes中勾选"Remote notifications"

b. 配置AppDelegate.m

代码语言:txt
复制
#import <Firebase.h>
#import <UserNotifications/UserNotifications.h>
#import <RNCPushNotificationIOS.h>

// 在didFinishLaunchingWithOptions中添加
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [FIRApp configure];
  
  // 请求通知权限
  UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
  [center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error) {
    if (granted) {
      dispatch_async(dispatch_get_main_queue(), ^{
        [application registerForRemoteNotifications];
      });
    }
  }];
  
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

// 处理注册APNs token
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
  [FIRMessaging messaging].APNSToken = deviceToken;
  [RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}

3. React Native端实现

a. 请求权限和获取token

代码语言:txt
复制
import messaging from '@react-native-firebase/messaging';
import {Platform} from 'react-native';

async function requestUserPermission() {
  const authStatus = await messaging().requestPermission();
  const enabled =
    authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
    authStatus === messaging.AuthorizationStatus.PROVISIONAL;

  if (enabled) {
    console.log('Authorization status:', authStatus);
    getFcmToken();
  }
}

async function getFcmToken() {
  try {
    const token = await messaging().getToken();
    console.log('FCM Token:', token);
    // 将token发送到你的服务器
  } catch (error) {
    console.log('Failed to get FCM token', error);
  }
}

b. 处理前台通知

代码语言:txt
复制
// 监听前台通知
messaging().onMessage(async remoteMessage => {
  console.log('Foreground notification:', remoteMessage);
  
  // 使用react-native-push-notification等库显示本地通知
  PushNotification.localNotification({
    title: remoteMessage.notification.title,
    message: remoteMessage.notification.body,
    // 其他自定义参数...
  });
});

c. 处理后台/退出状态通知

代码语言:txt
复制
// 设置后台消息处理器
messaging().setBackgroundMessageHandler(async remoteMessage => {
  console.log('Background notification:', remoteMessage);
  
  // 处理后台通知逻辑
  return Promise.resolve();
});

// 监听通知点击
messaging().onNotificationOpenedApp(remoteMessage => {
  console.log('Notification opened app:', remoteMessage);
  // 处理点击逻辑
});

// 检查应用是否通过通知启动
messaging()
  .getInitialNotification()
  .then(remoteMessage => {
    if (remoteMessage) {
      console.log('App opened from notification:', remoteMessage);
      // 处理启动逻辑
    }
  });

4. 自定义通知内容

要在iOS上显示自定义通知,需要在服务器端发送包含特定payload的通知:

代码语言:txt
复制
{
  "to": "DEVICE_FCM_TOKEN",
  "content_available": true,
  "priority": "high",
  "notification": {
    "title": "自定义标题",
    "body": "自定义内容",
    "sound": "default"
  },
  "data": {
    "customKey": "customValue",
    "click_action": "FLUTTER_NOTIFICATION_CLICK"
  }
}

5. 自定义通知UI

要实现完全自定义的通知UI,需要:

  1. 创建Notification Service Extension:
    • 在Xcode中: File -> New -> Target -> Notification Service Extension
    • 实现didReceive(_:withContentHandler:)方法
代码语言:txt
复制
import UserNotifications

class NotificationService: UNNotificationServiceExtension {
    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        guard let bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) else {
            return
        }
        
        // 修改通知内容
        bestAttemptContent.title = "\(bestAttemptContent.title) [modified]"
        bestAttemptContent.body = "\(bestAttemptContent.body) [modified]"
        
        // 添加自定义附件
        if let url = URL(string: "https://example.com/image.jpg"),
           let data = try? Data(contentsOf: url),
           let attachment = try? UNNotificationAttachment(identifier: "image", url: url, options: nil) {
            bestAttemptContent.attachments = [attachment]
        }
        
        contentHandler(bestAttemptContent)
    }
}

常见问题及解决方案

1. 通知不显示

  • 原因: 可能缺少必要的权限或配置
  • 解决:
    • 确保已正确配置APNs证书
    • 检查是否调用了registerForRemoteNotifications
    • 验证设备token是否有效

2. 自定义数据无法接收

  • 原因: iOS对通知payload有大小限制
  • 解决: 确保数据部分不超过4KB

3. 后台通知不触发

  • 原因: 可能缺少content_available: true标志
  • 解决: 在服务器端payload中添加此标志

4. 通知点击无响应

  • 原因: 未正确处理onNotificationOpenedAppgetInitialNotification
  • 解决: 确保正确设置了这些监听器

最佳实践

  1. 测试环境: 使用开发环境APNs证书进行开发测试
  2. 错误处理: 实现全面的错误处理和日志记录
  3. 性能优化: 对于大量通知,考虑使用通知组
  4. 用户体验: 提供清晰的通知设置选项给用户
  5. 安全: 验证通知来源,防止伪造通知攻击

通过以上步骤,你可以在React Native iOS应用中实现完整的自定义FCM推送通知功能,包括自定义UI和交互逻辑。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

领券