Golang FCM推送服务
在Golang中实现FCM推送服务时,如何正确处理设备令牌的更新和失效情况?我在使用Firebase Admin SDK时遇到部分设备收不到通知,但返回的响应中并没有错误信息。应该如何排查这类问题?另外,是否有最佳实践来管理批量推送时的速率限制和错误重试机制?
2 回复
Golang中可使用Firebase Admin SDK实现FCM推送。安装firebase.google.com/go包,通过服务账号JSON文件初始化应用,调用Messaging.Send方法发送通知。支持单设备、多设备和主题推送,需处理发送结果和错误。
更多关于Golang FCM推送服务的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Golang中实现FCM(Firebase Cloud Messaging)推送服务,可以使用官方的Firebase Admin SDK。以下是完整的实现步骤和代码示例:
1. 安装依赖
go get firebase.google.com/go
go get firebase.google.com/go/messaging
2. 初始化FCM客户端
package main
import (
"context"
"log"
firebase "firebase.google.com/go"
"firebase.google.com/go/messaging"
"google.golang.org/api/option"
)
func initializeApp() *messaging.Client {
// 使用服务账户密钥文件
opt := option.WithCredentialsFile("path/to/serviceAccountKey.json")
app, err := firebase.NewApp(context.Background(), nil, opt)
if err != nil {
log.Fatalf("error initializing app: %v\n", err)
}
client, err := app.Messaging(context.Background())
if err != nil {
log.Fatalf("error getting Messaging client: %v\n", err)
}
return client
}
3. 发送推送消息
func sendToToken(client *messaging.Client, token string) {
message := &messaging.Message{
Data: map[string]string{
"score": "850",
"time": "2:45",
},
Token: token, // 设备注册令牌
Notification: &messaging.Notification{
Title: "测试标题",
Body: "测试消息内容",
},
Android: &messaging.AndroidConfig{
Priority: "high", // 设置高优先级确保即时送达
},
}
response, err := client.Send(context.Background(), message)
if err != nil {
log.Fatalf("error sending message: %v\n", err)
}
log.Printf("Successfully sent message: %s\n", response)
}
func sendToTopic(client *messaging.Client, topic string) {
message := &messaging.Message{
Notification: &messaging.Notification{
Title: "主题消息",
Body: "这是一条发送到主题的消息",
},
Topic: topic, // 订阅主题名称
}
response, err := client.Send(context.Background(), message)
if err != nil {
log.Fatalf("error sending message: %v\n", err)
}
log.Printf("Successfully sent message: %s\n", response)
}
4. 订阅主题管理
func subscribeToTopic(client *messaging.Client, tokens []string, topic string) {
response, err := client.SubscribeToTopic(context.Background(), tokens, topic)
if err != nil {
log.Fatalf("error subscribing to topic: %v\n", err)
}
log.Printf("Successfully subscribed: %d tokens\n", response.SuccessCount)
}
func unsubscribeFromTopic(client *messaging.Client, tokens []string, topic string) {
response, err := client.UnsubscribeFromTopic(context.Background(), tokens, topic)
if err != nil {
log.Fatalf("error unsubscribing from topic: %v\n", err)
}
log.Printf("Successfully unsubscribed: %d tokens\n", response.SuccessCount)
}
5. 完整使用示例
func main() {
client := initializeApp()
// 发送给单个设备
sendToToken(client, "device_registration_token")
// 发送给主题
sendToTopic(client, "news")
// 管理主题订阅
tokens := []string{"token1", "token2"}
subscribeToTopic(client, tokens, "weather")
}
注意事项:
- 服务账户密钥:需要从Firebase控制台下载服务账户JSON文件
- 设备令牌:客户端需要正确集成FCM SDK并获取注册令牌
- 错误处理:实际生产环境需要完善的错误处理和重试机制
- 消息限制:注意FCM的消息大小限制(4KB)
这种方式支持单设备推送、主题推送和条件消息,可以满足大多数推送场景需求。

