Firebase推送通知image字段为null时发送报错的解决方法
问题根因
FCM v1 接口的所有图片相关字段(安卓的image_url、APNs的fcm_options.image、WebPush的headers.image)不接受null值,无图片场景下不能显式给这些字段赋值null,必须直接从payload结构里移除对应字段,否则接口会直接返回参数校验错误。另外原代码存在结构错误:webpush配置被错误嵌套在了apns节点内部,会导致Web端推送配置完全不生效。
修复方案
- 先构造不含图片字段的基础公共payload,再根据是否存在有效图片地址,动态决定是否追加各平台的图片配置字段
- 修正payload结构错误,把
webpush节点从apns内部移到和android、apns同级的位置 - 纯文本无图场景下,所有平台的图片相关字段都不要写入payload,禁止传null/空字符串
- 云函数内的异步推送逻辑要加
await,避免函数提前终止导致推送发送失败
修复后的完整可运行代码如下:
export const sendChatNotification = functions.firestore.document('chatrooms/{chatroomId}/chats/{chatId}').onCreate(async (snap, ctx) => { const token = snap.get('sendToDeviceToken'); const sender = snap.get('fullSenderName'); const body = snap.get('message'); const tokens = [token]; console.log('Tokens: ' + tokens); // 判断消息类型 const isImageMsg = body.startsWith('https://firebasestorage.googleapis.com'); const message = isImageMsg ? 'Image Received' : body; const imageUrl = isImageMsg ? body : null; // 构造基础payload,默认不携带任何图片字段 const payload = { tokens: tokens, notification: { title: sender, body: message, }, android: { notification: { channel_id: "roofdeck_default", title: sender, body: message, notification_priority: 'priority_max', color: '#DDE9F7', icon: '@mipmap/ic_launcher', }, }, apns: { payload: { aps: { badge: 1, }, }, }, // 修正原结构错误:webpush与android、apns节点同级 webpush: { headers: {} } }; // 仅当存在有效图片地址时,才给各平台追加图片配置,无图时完全不传递对应字段 if (imageUrl) { payload.android.notification.image_url = imageUrl; payload.apns.payload.fcm_options = { image: imageUrl }; payload.webpush.headers.image = imageUrl; } // 等待推送发送完成再返回结果,避免函数实例提前回收 try { const response = await fcm.sendMulticast(payload); console.log('Successfully sent message:', response); return {success: true}; } catch (error) { console.log('Error on sent message:', error); return {error: error.code}; } });
额外注意事项
- 不要给图片字段传空字符串
'',同样会触发FCM参数校验错误,无图场景直接省略字段即可 - 判断图片链接时用
startsWith比手动截取固定长度前缀更稳妥,避免后续存储域名前缀长度变化导致判断失效 - 云函数内所有异步操作必须加
await,否则会出现推送随机发送失败的问题
内容的提问来源于stack exchange,提问作者Rene Alas
相关产品推荐
相关产品推荐

