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

.NET调用FCM V1 API发通知遇APNS/Web Push认证错误求助

FCM V1 API发送通知时APNS/Web Push认证错误排查

问题描述

我正在尝试使用Firebase Cloud Messaging API (V1)发送通知,React应用中使用相同项目配置能正常生成设备令牌,但在.NET API项目发送消息时,抛出APNS或Web推送服务认证错误。已确认账号具备全部权限,仍未找到问题根源,请求帮忙排查。

相关代码

发送通知的Action方法

[HttpPost("notification")]
public async Task<IActionResult> SendMessage(SingleMessageRequest request)
{
    var messaging = FirebaseMessaging.DefaultInstance;
    if (messaging == null)
    {
        notificationService.GetFirebaseApp();
        messaging = FirebaseMessaging.DefaultInstance;
    }

    var message = new Message()
    {
        Data = new Dictionary<string, string>()
        {
            ["Name"] = request.data.Name,
            ["Email"] = request.data.Email
        },
        Notification = new FirebaseAdmin.Messaging.Notification
        {
            Title = request.notification.title,
            Body = request.notification.body
        },
        Token = request.token,
        //Topic = request.topic
    };

    var result = await messaging.SendAsync(message);
    return new OkObjectResult(result);
}

Firebase配置服务

public interface INotificationService
{
    public FirebaseApp GetFirebaseApp();
}

public class NotificationService : INotificationService
{
    public FirebaseApp GetFirebaseApp()
    {
        var credentials = FirebaseApp.Create(new AppOptions()
        {
            Credential = GoogleCredential.FromFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "key.json")),
        });

        return credentials;
    }
}

错误详情

FirebaseAdmin.Messaging.FirebaseMessagingException: Auth error from APNS or Web Push Service
   at FirebaseAdmin.Util.ErrorHandlingHttpClient`1.SendAndReadAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at FirebaseAdmin.Util.ErrorHandlingHttpClient`1.SendAndDeserializeAsync[TResult](HttpRequestMessage request, CancellationToken cancellationToken)
   at FirebaseAdmin.Messaging.FirebaseMessagingClient.SendAsync(Message message, Boolean dryRun, CancellationToken cancellationToken)
   at FirebaseAdmin.Messaging.FirebaseMessaging.SendAsync(Message message, Boolean dryRun, CancellationToken cancellationToken)
   at FirebaseAdmin.Messaging.FirebaseMessaging.SendAsync(Message message, Boolean dryRun)
   at FirebaseAdmin.Messaging.FirebaseMessaging.SendAsync(Message message)
   at FirebaseCloudMessagingPOC.Controllers.NotificationController.SendMessage(SingleMessageRequest request) in C:\Users\Vijay.Parmar\source\repos\FirebaseCloudMessagingPOC\FirebaseCloudMessagingPOC\Controllers\NotificationController.cs:line 73
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

排查方案

  • 修复Firebase App初始化逻辑
    现有代码每次调用GetFirebaseApp都会创建新实例,会导致凭证冲突。修改为优先复用已有实例:

    public FirebaseApp GetFirebaseApp()
    {
        try
        {
            return FirebaseApp.DefaultInstance;
        }
        catch
        {
            var credentials = FirebaseApp.Create(new AppOptions()
            {
                Credential = GoogleCredential.FromFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "key.json")),
            });
            return credentials;
        }
    }
    
  • 验证key.json有效性
    确认文件路径正确,private_key和client_email字段未被篡改;检查该服务账号在Firebase控制台项目设置>服务账号中存在,且已启用Cloud Messaging API权限。

  • APNS配置检查(iOS设备)
    若推送iOS设备,确认Firebase控制台项目设置>云消息传递中APNs认证配置正确:上传有效证书或配置APNs密钥,且密钥包含推送权限;同时验证设备令牌环境(开发/生产)与API使用的key.json环境一致。

  • Web Push配置检查(Web设备)
    若推送Web应用,确认Firebase控制台项目设置>云消息传递中Web推送证书配置正确,且React端使用的vapidKey与控制台一致;检查服务账号在Google Cloud控制台IAM>权限中拥有firebase.messaging相关权限。

  • 测试dry-run模式
    开启dry-run模式模拟发送流程,定位是认证还是消息格式问题:

    var result = await messaging.SendAsync(message, dryRun: true);
    
  • 检查网络连通性
    确认.NET API服务器能正常访问https://fcm.googleapis.com,未被防火墙或代理拦截。


内容的提问来源于stack exchange,提问作者Vijay Parmar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 02:05:24