React Native后台/杀死状态下推送通知无法显示图片/视频求助
解决React Native后台/杀死状态下推送通知显示图片/视频的问题
你遇到的问题核心是:前台时通知由App内的@notifee/react-native主动展示,能正常处理附件;但后台/杀死状态下,iOS由APNs、Android由FCM系统直接处理推送,此时无法依赖App内的代码逻辑加载媒体附件,需要针对不同平台做配置调整:
一、iOS平台处理步骤
- 添加Notification Service Extension
iOS需要通过这个扩展在推送到达时下载并附加媒体,否则APNs只会显示基础标题和内容。- 在Xcode中打开项目,选择
File > New > Target,选择Notification Service Extension完成创建并启用。 - 在扩展的
NotificationService.swift中添加媒体下载逻辑,示例代码:override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { self.contentHandler = contentHandler bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) guard let content = bestAttemptContent, let mediaUrlString = content.userInfo["video"] as? String, let mediaUrl = URL(string: mediaUrlString) else { contentHandler(request.content) return } // 下载媒体到临时目录 let task = URLSession.shared.downloadTask(with: mediaUrl) { [weak self] tempUrl, response, error in guard let self = self, let tempUrl = tempUrl else { contentHandler(request.content) return } let fileManager = FileManager.default let tempDir = NSTemporaryDirectory() let fileName = mediaUrl.lastPathComponent let destUrl = URL(fileURLWithPath: tempDir).appendingPathComponent(fileName) do { if fileManager.fileExists(atPath: destUrl.path) { try fileManager.removeItem(at: destUrl) } try fileManager.moveItem(at: tempUrl, to: destUrl) // 添加媒体附件到通知 let attachment = try UNNotificationAttachment(identifier: "media", url: destUrl, options: nil) content.attachments = [attachment] self.contentHandler(content) } catch { self.contentHandler(request.content) } } task.resume() }
- 在Xcode中打开项目,选择
- 推送Payload必须包含
mutable-content: 1
发送推送时,payload需添加该字段,告知APNs允许扩展修改通知内容:{ "aps": { "alert": { "title": "标题", "body": "内容" }, "mutable-content": 1, "sound": "default" }, "video": "https://your-media-url.com/video.mp4" }
二、Android平台处理步骤
- 修正后台消息处理逻辑
后台消息在Headless JS环境中运行,需确保@notifee/react-native初始化正常,同时适配Android的附件配置,注意从remoteMessage.data中读取字段(后台时remoteMessage.notification可能为空):
修改你的onMessageReceived函数:async function onMessageReceived(message) { const title = message.notification?.title || message.data.title; const body = message.notification?.body || message.data.body; const mediaUrl = message.data.video; const notificationOptions = { title, body, ios: { sound: 'default', attachments: mediaUrl ? [{ url: mediaUrl, thumbnailTime: 3 }] : [] }, android: { channelId: 'media-notification-channel', // 提前创建支持媒体的通知渠道 sound: 'default', attachments: mediaUrl ? [{ uri: mediaUrl }] : [] // Android使用uri字段配置附件 } }; await notifee.displayNotification(notificationOptions); } - 创建支持媒体的通知渠道
在App启动时创建对应渠道,确保通知权限配置正确:import notifee from '@notifee/react-native'; import { AndroidImportance } from '@notifee/react-native'; async function createMediaChannel() { await notifee.createChannel({ id: 'media-notification-channel', name: '媒体通知', importance: AndroidImportance.HIGH, sound: 'default', }); } // 在App初始化时调用该函数 createMediaChannel(); - 推送Payload配置
发送给FCM的payload需将媒体URL放在data字段中,示例:{ "data": { "title": "标题", "body": "内容", "video": "https://your-media-url.com/video.mp4" }, "notification": { "title": "标题", "body": "内容", "sound": "default" } }
三、通用注意事项
- 媒体URL必须可公开访问,或配置了正确的权限验证,确保设备能在后台完成下载。
- iOS的Notification Service Extension需与主App使用相同的签名配置。
- Android需确保App拥有
INTERNET权限,Android 10+设备还需ACCESS_NETWORK_STATE权限以支持后台网络操作。
内容的提问来源于stack exchange,提问作者Rajat
相关产品推荐
相关产品推荐

