Firebase Cloud Messaging推送内容不生效,求正确实现方案
问题分析与修正方案
你的问题核心是FCM请求体格式不符合官方规范,加上几个细节处理不到位,导致请求返回成功但消息无法送达设备。下面是完整的修正实现:
一、现有代码的核心问题
- 请求体结构错误:FCM要求将通知栏展示内容、自定义业务数据、目标设备令牌拆分为不同层级字段,你的模型把所有字段混在一起,FCM无法解析有效推送指令。
StringContent未指定媒体类型:默认是text/plain,FCM仅接受application/json格式的请求体。- 异步方法未正确等待:
ReadAsStringAsync()是异步方法,未用await会导致无法获取完整响应内容用于排查问题。 - 目标字段
to位置错误:to属于请求体顶级字段,不能放在自定义数据中。
二、正确的模型定义
按照FCM官方规范,拆分请求体结构:
// FCM请求主模型 public class FcmRequest { // 目标设备令牌/主题/条件表达式 [JsonPropertyName("to")] public string To { get; set; } // 通知栏展示内容(可选,仅发自定义数据可省略) [JsonPropertyName("notification")] public FcmNotification Notification { get; set; } // 自定义业务数据(可选) [JsonPropertyName("data")] public FcmData Data { get; set; } // 可选配置:允许修改通知样式(如大图、媒体) [JsonPropertyName("mutable_content")] public bool MutableContent { get; set; } = true; // 通知音效 [JsonPropertyName("sound")] public string Sound { get; set; } = "default"; } // 通知栏内容模型 public class FcmNotification { [JsonPropertyName("title")] public string Title { get; set; } [JsonPropertyName("body")] public string Body { get; set; } } // 自定义业务数据模型 public class FcmData { [JsonPropertyName("from")] public string From { get; set; } [JsonPropertyName("read")] public bool Read { get; set; } // 可添加更多自定义字段 }
三、修正后的后端请求代码
// 建议复用HttpClient(可通过依赖注入注册为单例,避免频繁创建连接) using var client = new HttpClient(); var request = new HttpRequestMessage(HttpMethod.Post, "https://fcm.googleapis.com/fcm/send?project_id=bespaargroen-370414"); // 设置授权头:确保使用Firebase控制台的Cloud Messaging Server Key request.Headers.Add("Authorization", "Bearer AAAA4u_fn_I:MyKey"); // 构建FCM请求内容 var fcmRequest = new FcmRequest { To = "目标设备的FCM令牌", Notification = new FcmNotification { Title = "自定义通知标题", Body = "自定义通知内容" }, Data = new FcmData { From = "发送方标识", Read = false }, MutableContent = true, Sound = "default" }; // 序列化并设置请求体,指定媒体类型为application/json var jsonContent = JsonConvert.SerializeObject(fcmRequest); request.Content = new StringContent(jsonContent, Encoding.UTF8, "application/json"); // 异步发送请求并等待响应 var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); // 获取响应内容用于调试(即使请求成功,FCM可能返回送达失败的具体原因) var responseJson = await response.Content.ReadAsStringAsync(); // 可将responseJson存入日志,方便排查问题 return new BoolResponse() { Success = true, Message = "Bericht verzenden gelukt" };
四、关键注意事项
- Server Key有效性:必须使用Firebase控制台「项目设置」→「Cloud Messaging」中的「Cloud Messaging API (Legacy)」Server Key,不要用Web API Key。
- 设备令牌有效性:目标设备的FCM令牌需是最新的,若应用卸载、令牌过期或设备离线,FCM会返回成功但消息无法送达。
- 权限配置:确保Firebase项目已启用Cloud Messaging API,若设置了IP限制,需将服务器IP加入允许列表。
- 调试响应:即使
EnsureSuccessStatusCode()通过,也要检查responseJson,FCM可能返回success: 0并给出具体错误(如令牌无效、主题不存在)。
内容的提问来源于stack exchange,提问作者NietTeDoen
相关产品推荐
相关产品推荐

