You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin.iOS调用FCM推送API返回InvalidRegistration错误求助

问题背景

在Xamarin iOS项目中通过RegisteredForRemoteNotifications方法获取设备DeviceToken,存入Preferences后再通过基于Entity Framework的API接口同步到服务端数据库,后续调用FCM接口发送推送时返回InvalidRegistration错误。

客户端获取DeviceToken代码(AppDelegate.cs)

public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
    byte[] bytes = deviceToken.ToArray<byte>();
    string[] hexArray = bytes.Select(b => b.ToString("x2")).ToArray();
    DeviceToken = string.Join(string.Empty, hexArray);

    Preferences.Set("TokenDevice", DeviceToken);
}

当前获取到并存入数据库的DeviceToken值为:

6b60feecad920471ccde5a3447ab22d3f820abae821daeac726cc7e6d0863465

服务端推送接口代码

[HttpPost]
public void SendNotification(string devicetoken, string title, string body, string link, string icon)
{
    try
    {
        dynamic data = new
        {
            to = devicetoken, 
            priority = "high",
            notification = new
            {
                title = title,
                body = body,
                link = link,
                icon = icon
            }
        };

        var json = JsonConvert.SerializeObject(data);
        Byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(json);

        string SERVER_API_KEY = "AAAAqOId6Is:APA91bHJ5pQgLlanU8gwQwnpxdBlKS00i1xxxxxxxxxxxxxxxxxxxxxxxxxxx";
        string SENDER_ID = "72xxxxxxxx";

        WebRequest tRequest;
        tRequest = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
        tRequest.Method = "post";
        tRequest.ContentType = "application/json";
        tRequest.Headers.Add(string.Format("Authorization: key={0}", SERVER_API_KEY));

        tRequest.Headers.Add(string.Format("Sender: id={0}", SENDER_ID));

        tRequest.ContentLength = byteArray.Length;
        Stream dataStream = tRequest.GetRequestStream();
        dataStream.Write(byteArray, 0, byteArray.Length);
        dataStream.Close();

        WebResponse tResponse = tRequest.GetResponse();

        dataStream = tResponse.GetResponseStream();

        StreamReader tReader = new StreamReader(dataStream);

        String sResponseFromServer = tReader.ReadToEnd();

        tReader.Close();
        dataStream.Close();
        tResponse.Close();
    }
    catch (Exception)
    {
        throw;
    }
}

代码中SERVER_API_KEY和SENDER_ID均从Firebase控制台项目设置-Cloud Messaging板块获取。

错误现象

调用推送接口测试时,FCM返回如下错误:

{"multicast_id":7343900550378569449,"success":0,"failure":1,"canonical_ids":0, "results":[{"error":"InvalidRegistration"}]}

核心诉求:希望沿用现有支持自定义跳转link、icon参数的代码逻辑,确认现有推送代码是否过时,以及InvalidRegistration错误的产生原因和修复方案。


问题解答

现有推送代码是否过时

当前使用的FCM旧版HTTP发送接口(https://fcm.googleapis.com/fcm/send)仍可正常调用,未完全停止服务,只是谷歌官方已推荐迁移到HTTP v1版本。旧版接口本身不会触发InvalidRegistration错误,现有自定义通知参数的逻辑可以完全保留,不需要推翻重写。

InvalidRegistration错误根本原因

存入数据库的64位十六进制字符串是苹果APNs服务的原生DeviceToken,不是FCM服务认可的注册Token,两类Token完全不通用,FCM无法识别APNs原生Token,直接返回注册无效错误。
现有代码只处理了原生APNs注册回调,没有接入Firebase Messaging SDK的Token获取逻辑:FCM需要先拿到APNs Token,再向谷歌服务端注册换取专属的FCM注册Token,这类Token格式为长字符串、中间带冒号分隔符,和当前获取的64位十六进制Token有明显区别,只有这个FCM Token才能作为推送接口的to参数使用。

修复方案

  1. 完成Xamarin.iOS端Firebase Messaging基础配置
    • 将GoogleService-Info.plist文件加入iOS项目,设置正确的生成操作
    • 在AppDelegate的FinishedLaunching方法中初始化Firebase App,配置Messaging代理,申请推送权限
  2. 修正Token获取逻辑,不要直接存储APNs Token用于FCM推送
    参考代码如下:
    // FinishedLaunching方法中加入初始化逻辑
    Firebase.Core.App.Configure();
    Messaging.SharedInstance.Delegate = this;
    
    // 实现Firebase Messaging的Token回调,这里拿到的才是可用于FCM推送的有效Token
    [Export("messaging:didReceiveRegistrationToken:")]
    public void DidReceiveRegistrationToken(Messaging messaging, string fcmToken)
    {
        // 存储fcmToken到本地,同步到服务端数据库
        Preferences.Set("TokenDevice", fcmToken);
    }
    
    // 原有RegisteredForRemoteNotifications方法保留,作用仅为将APNs Token传递给FCM SDK
    public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
    {
        Messaging.SharedInstance.ApnsToken = deviceToken;
    }
    
  3. 服务端代码无需大改,将数据库中之前存储的所有APNs原生Token替换为新获取的FCM Token,再调用发送接口即可解决InvalidRegistration错误,原有自定义title、body、link、icon的逻辑完全不受影响。
  4. 额外注意事项:开发环境测试时需使用沙盒环境对应的FCM Token,同时要在Firebase控制台正确上传对应环境的APNs证书,发送请求时可加上"mutable_content": true参数,避免因环境不匹配导致推送失败。

内容的提问来源于stack exchange,提问作者Chim Di Tru

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 12:42:17