Firebase云函数TypeScript推送payload报错:loc-args值无效
我来帮你解决这个困扰!你遇到的这个报错,其实是FCM(Firebase Cloud Messaging)对推送payload的结构要求和原生iOS略有差异导致的,看起来你的代码逻辑没问题,但放错位置啦。
先再确认下你收到的报错:
Error: Messaging payload contains an invalid value for the "notification.loc-args" property. Values must be strings.
先看你的TypeScript代码:
var values : String[] = []; values.push('Johnny Appleseed'); const payload = { notification: { 'title-loc-key': 'INVITE_PUSH_TITLE', 'loc-key': 'INVITE_PUSH_BODY', 'loc-args': values, 'type': 'Invite', 'fromName': name, 'userId': uid, } };
问题根源
FCM的notification字段是预定义的通用通知模板,它对loc-args的处理逻辑比较特殊:本地化参数不能直接放在notification根节点下,而是需要嵌套在alert对象中(和苹果官方的Payload格式对齐),或者把自定义数据迁移到data字段里。
你贴的苹果官方示例其实已经给出了正确的结构方向,只是FCM需要你通过特定字段来传递这个原生格式。
解决方案(推荐和苹果官方对齐的写法)
直接通过FCM的apns.payload字段构造符合iOS要求的原生Payload,这样完全不会有解析问题:
var values : String[] = []; values.push('Johnny Appleseed'); const payload = { // 专门针对iOS的APNs配置,完全对齐苹果官方格式 apns: { payload: { aps: { alert: { 'title-loc-key': 'INVITE_PUSH_TITLE', 'loc-key': 'INVITE_PUSH_BODY', 'loc-args': values } } } }, // 自定义的业务数据放在data字段里,不要混在notification模板中 data: { 'type': 'Invite', 'fromName': name, 'userId': uid, } };
补充说明
为什么之前的写法会报错?因为FCM在处理notification根节点的loc-args时,会尝试把它转换为适配多平台的格式,这个过程中可能误判了数组的类型;而直接通过apns.payload传递原生iOS格式,就完全遵循苹果文档的要求,不会触发这个错误。
再对照你贴的苹果官方示例:
苹果本地化字符串:
"GAME_PLAY_REQUEST_FORMAT" = "%@ and %@ have invited you to play Monopoly";
苹果Payload示例:
{ "aps" : { "alert" : { "loc-key" : "GAME_PLAY_REQUEST_FORMAT", "loc-args" : [ "Jenna", "Frank"] } } }
我们的解决方案就是把这个原生结构嵌套到FCM的apns.payload中,完美匹配苹果的要求,同时把自定义的业务数据(比如type、userId)放到data字段,这也是FCM推荐的最佳实践。
内容的提问来源于stack exchange,提问作者ayalcin

