Firebase主题推送无法接收问题排查求助(附Go实现代码)
问题:Firebase主题推送返回message_id但设备无法接收
已将设备Token订阅至Firebase主题,向该主题发送消息时虽返回message_id,但Android和iOS设备均无法接收。
补充说明:Android和iOS设备测试结果一致。
已验证的有效场景:
- 直接向设备Token发送消息,设备可正常接收;
- 将同一Token订阅至主题,响应显示绑定成功(成功数为1);
- Firebase Cloud Messaging控制台中可看到刚订阅的主题;
以上信息说明Token、主题及订阅操作均有效。
请问有哪些排查步骤或解决方法?
排查步骤与解决方法
1. 完善跨平台推送配置
- Android端:当前代码已设置
Priority: "high",需确认设备厂商系统是否拦截低优先级通知,同时检查AndroidNotification的图标路径是否正确,部分系统会因图标缺失隐藏通知; - iOS端:在主题推送的
message中添加APNSConfig配置,设置APNSPriority: 10(高优先级),并补充Sound参数,iOS默认可能不会展示无声音的静默通知。
2. 校验主题名称一致性
确认发送主题消息时使用的fm.Topic与订阅时的主题名称完全匹配,包括大小写、特殊字符(如下划线、斜杠),Firebase主题名称区分大小写。
3. 等待主题订阅同步延迟
Firebase主题订阅操作存在异步同步延迟,可能需要几分钟才能在系统中生效。若刚完成订阅就测试推送,可等待10-15分钟后重试。
4. 查看设备端日志排查
- Android:通过Logcat过滤
FirebaseMessaging标签,查看是否有主题消息接收日志,排查是否被系统拦截或解析失败; - iOS:通过Xcode控制台查看APNs相关日志,确认设备是否收到推送,排查证书权限或系统设置问题。
5. 对比控制台推送参数
直接在Firebase控制台向该主题发送测试消息,若控制台推送成功,说明代码中的消息构造存在问题,对比控制台生成的Payload与代码中message的差异,重点检查Notification、Data字段的完整性。
6. 验证Firebase实例一致性
确认主题推送使用的Firebase App实例,与Token推送、订阅操作使用的是同一个实例,避免多实例导致的订阅与推送数据不互通。
相关Go代码
初始化Firebase App(正常工作)
func NewFirebaseNotifier() (IExternal, error) { var app *firebase.App var err error if config.GetSystemENV().RunMode == config.RunModeLocal { projectID := config.GetFirebaseEnv().ProjectID opt := option.WithCredentialsFile(projectID) app, err = firebase.NewApp(context.Background(), nil, opt) if err != nil { return nil, errors.New("error initializing app: " + err.Error()) } } else { projectConfig := &firebase.Config{ProjectID: config.GetFirebaseEnv().ProjectID} if config.GetFirebaseEnv().ProjectID == "" { projectConfig = nil } app, err = firebase.NewApp(context.Background(), projectConfig) if err != nil { return nil, errors.New("error initializing app: " + err.Error()) } } if config.GetSystemENV().RunMode != config.RunModeProduction { fmt.Println("Firebase app initialized", app) } return &FirebaseNotifier{app: app}, nil }
向Token推送消息(正常工作)
func (e *FirebaseNotifier) SendMessageToTokens(fm dto.PushMessageTokens) *dto.APIError { if err := checkMessage(fm.Message); err != nil { return &dto.APIError{ Err: err, StatusCode: apiprotocol.RequestErr, } } ctx := context.Background() fmt.Println("tokens app:", e.app) client, err := e.app.Messaging(ctx) if err != nil { return &dto.APIError{ Err: errors.New("error getting Messaging client: " + err.Error()), StatusCode: apiprotocol.FirebaseClientErr, } } // See documentation on defining a message payload. message := &messaging.MulticastMessage{ Notification: &messaging.Notification{ Title: fm.Message.Title, Body: fm.Message.Body, ImageURL: fm.Message.ImageURL, }, Android: &messaging.AndroidConfig{ Priority: "high", Notification: &messaging.AndroidNotification{ Icon: "stock_ticker_update", Color: "#0000FF", }, }, Tokens: fm.Tokens, Data: fm.Data, } // Send a message to the devices subscribed to the provided topic. response, err := client.SendEachForMulticast(ctx, message) if err != nil { return &dto.APIError{ Err: errors.New("error sending Messaging: " + err.Error()), StatusCode: apiprotocol.FirebaseSendMessageErr, } } if config.GetSystemENV().RunMode != config.RunModeProduction { // Response is a message ID string. fmt.Println("message tokens:", fm) fmt.Println("Successfully sent message:", response) } return nil }
订阅主题(正常工作)
func (e *FirebaseNotifier) SubscribeTopic(fs dto.Subscription) *dto.APIError { ctx := context.Background() client, err := e.app.Messaging(ctx) if err != nil { return &dto.APIError{ Err: errors.New("error getting Messaging client: " + err.Error()), StatusCode: apiprotocol.FirebaseClientErr, } } response, err := client.SubscribeToTopic(ctx, fs.DeviceIDs, fs.Topic) if err != nil { log.Fatalln(err) } if config.GetSystemENV().RunMode != config.RunModeProduction { fmt.Println("subscribe success:", fs) if response.FailureCount > 0 { // List of errors in the same order as the registration tokens. for idx, err := range response.Errors { fmt.Println("Failed to subscribe to token:", fs.DeviceIDs[idx], "error:", err) } } fmt.Println(response.SuccessCount, "tokens were subscribed successfully, tokens: ", fs.DeviceIDs) } return nil }
向主题推送消息(无法正常工作)
func (e *FirebaseNotifier) SendMessageToTopic(fm dto.PushMessageTopic) *dto.APIError { if err := checkMessage(fm.Message); err != nil { return &dto.APIError{ Err: err, StatusCode: apiprotocol.RequestErr, } } ctx := context.Background() fmt.Println("topic app:", e.app) client, err := e.app.Messaging(ctx) if err != nil { return &dto.APIError{ Err: errors.New("error getting Messaging client: " + err.Error()), StatusCode: apiprotocol.FirebaseClientErr, } } // See documentation on defining a message payload. message := &messaging.Message{ Notification: &messaging.Notification{ Title: fm.Message.Title, Body: fm.Message.Body, ImageURL: fm.Message.ImageURL, }, Android: &messaging.AndroidConfig{ Priority: "high", Notification: &messaging.AndroidNotification{ Icon: "stock_ticker_update", Color: "#f45342", }, }, Topic: fm.Topic, Data: fm.Data, } // Send a message to the devices subscribed to the provided topic. response, err := client.Send(ctx, message) if err != nil { return &dto.APIError{ Err: errors.New("error sending Messaging: " + err.Error()), StatusCode: apiprotocol.FirebaseSendMessageErr, } } if config.GetSystemENV().RunMode != config.RunModeProduction { // Response is a message ID string. fmt.Println("message topic:", message) fmt.Println("Successfully sent message:", response) } return nil }
内容的提问来源于stack exchange,提问作者YUHO
相关产品推荐
相关产品推荐

