如何解决Expo推送通知中的MismatchSenderId错误?
问题描述
我正在尝试使用Expo Server实现推送通知,已按官方文档配置前后端,完成Firebase相关配置并执行expo push:android:upload --api-key命令上传了Firebase Cloud Messaging的Server Key。但打包APK部署后,后端日志出现以下错误:
chunk [ { to: 'ExponentPushToken[xxxxxxxxxxxxxxxxxx]', sound: 'default', body: 'MyApp', data: { withSome: 'data' } } ] ticket chunk [ { id: '37153ff5-a52b-4a36-8973-b3845211d8f9', status: 'error', message: "There was an unknown error with the FCM server. See this error's details for more information.", messageEnum: 16, details: { error: 'ProviderError', errorCodeEnum: 1, fault: 'fcm', fcm: [Object] } } ] ticket Chunk fcm object access: { error: 'MismatchSenderId' }
后端代码如下:
exports.pushNotification = asyncHandler(async (req, res, next) => { const { somePushTokens } = req.body; let allToken = []; for (let i in somePushTokens) { allToken.push(somePushTokens[i].token); } let expo = new Expo({ accessToken: "xxxxxxxxxxxxxxxxxxxxxxxxxx", }); let messages = []; for (let pushToken of allToken) { if (!Expo.isExpoPushToken(pushToken)) { console.error(`Push token ${pushToken} is not a valid Expo push token`); continue; } messages.push({ to: pushToken, sound: "default", body: "MyApp", data: { withSome: "data" }, }); } let chunks = expo.chunkPushNotifications(messages); console.log("chunks", chunks); let tickets = []; (async () => { for (let chunk of chunks) { console.log("chunk", chunk); try { let ticketChunk = await expo.sendPushNotificationsAsync(chunk); console.log("ticket chunk", ticketChunk); console.log("ticket Chunk fcm object access:", ticketChunk[0].details.fcm); tickets.push(...ticketChunk); } catch (error) { console.error("Error ticket chunk", error); } } })(); let receiptIds = []; for (let ticket of tickets) { if (ticket.id) { receiptIds.push(ticket.id); } } let receiptIdChunks = expo.chunkPushNotificationReceiptIds(receiptIds); (async () => { for (let chunk of receiptIdChunks) { try { let receipts = await expo.sendPushNotificationsAsync(chunk); console.log("recipts: ", receipts); for (let receiptId in receipts) { let { status, message, details } = receipts[receiptId]; if (status === "ok") { continue; } else if (status === "error") { console.error( `There was an error sending a notification: ${message}` ); console.error(`The error code in status is: ${details.error}`); console.error(`The error fcm in status is": ${details.fcm}`); if (details && details.error && details.fcm) { console.error(`The error code is: ${details.error}`); console.error(`The error fcm is": ${details.fcm}`); } } } } catch (error) { console.error("The error: ", error); } } })(); res.status(200).json({ success: true, data: messages, msg: "Notification has been send", }); });
解决方法
核对FCM密钥所属项目
确保你上传的FCM Server Key,和生成当前Expo Push Token的Firebase项目是同一个。每个Firebase项目的Sender ID与Server Key绑定,跨项目使用必然触发MismatchSenderId错误。验证Expo项目的Firebase配置文件
检查app.json或app.config.js中的android.googleServicesFile配置,确认对应的google-services.json来自正确的Firebase项目,文件内的sender_id必须和上传Server Key的项目一致。替换旧的Push Token
如果之前用其他Firebase项目生成过Push Token,这些旧Token和当前Sender ID不兼容。需要让用户重新安装APP生成新Token,或者在后端过滤掉无效的旧Token。确认Expo accessToken有效性
初始化Expo实例时使用的accessToken必须是当前Expo项目的有效令牌,确保Expo服务器能正确关联到你的Firebase配置信息。重新上传FCM密钥
若之前上传密钥过程中出现异常,重新执行expo push:android:upload --api-key <你的FCM Server Key>命令,确保密钥成功上传到Expo服务器。
内容的提问来源于stack exchange,提问作者van123

