firebase / firebase/firebase-admin-node

Misleading error message for THIRD_PARTY_AUTH_ERROR: raw "OAuth 2 access token" text surfaced instead of the APNs-specific message

未关闭
#3,215 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
api: messaging
主要语言
TypeScript
星标
1.7k
派生
419
平均合并
3 天 10 小时
30 天内合并 PR
16

描述

## Summary

When FCM rejects an iOS send with `UNAUTHENTICATED`, the SDK surfaces the raw
gateway message ("...Expected OAuth 2 access token...") instead of its own
APNs-specific message, even though the error is classified as
`messaging/third-party-auth-error`. This sends developers down the wrong path
(debugging their own service-account / OAuth setup) when the real cause is a
downstream APNs credential problem.

## What happened

Sending to iOS device tokens, some tokens fail with:

```json
HTTP 401
{
"error": {
"code": 401,
"status": "UNAUTHENTICATED",
"message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. ...",
"details": [{ "@type": "...FcmError", "errorCode": "THIRD_PARTY_AUTH_ERROR" }]
}
}
```

`error.code` is correctly `messaging/third-party-auth-error`, but `error.message`
is the raw *"Expected OAuth 2 access token"* text. That message strongly implies
a problem with the caller's own authentication (service account / access token),
so it's natural to spend several debugging cycles verifying OAuth, the service
account, token refresh, etc. — all of which are fine. The actual cause is on the
APNs side (e.g. an APNs auth key/certificate that doesn't cover the environment a
given token was minted in). The misleading message cost us multiple debugging
rounds before we inspected `details[].errorCode`.

## Root cause in the SDK

In `src/messaging/error.ts` on current `main`:

- `UNAUTHENTICATED` is mapped to `THIRD_PARTY_AUTH_ERROR` (line ~201), and there is
a clear canonical message for it (lines ~133–137):

> "A message targeted to an iOS device could not be sent because the required
> APNs SSL certificate was not uploaded or has expired. Check the validity of
> your development and production certificates."

- But the error message is assigned as (line ~260):

```ts
error.message = message || error.message;
```

Since the raw server `message` is truthy, it always wins, so the SDK's own
clearer, APNs-specific message is never shown for this code — the misleading
"OAuth 2 access token" text is surfaced instead.

## A second, smaller issue: the canonical message is dated

Even when shown, the canonical message only mentions an *"APNs SSL certificate"*
and *"development and production certificates"* — i.e. the `.p12` model. Modern
setups use `.p8` **APNs auth keys** (token-based auth), and Web Push uses VAPID
keys. For those, "certificate ... has expired / check your certificates" is
itself misleading, because there is no certificate involved.

## Suggested fix

1. For `third-party-auth-error`, prefer (or prepend) the SDK's canonical message
rather than the raw `UNAUTHENTICATED` gateway text, since that raw text
systematically points debugging in the wrong direction. The raw text can be
kept as "Raw server response: ..." (the SDK already appends that in some
paths).
2. Update the canonical message to cover APNs **auth keys (`.p8`)** and **Web Push
(VAPID)**, not just SSL certificates.

## Environment

- Verified against current `main`, `src/messaging/error.ts`.
- Reproduced on a real send to an affected iOS token (401 / UNAUTHENTICATED /
`details[].errorCode = THIRD_PARTY_AUTH_ERROR`).

Happy to open a PR along the lines of the suggested fix if this direction sounds right.

贡献指南

打开贡献指南

调研方向

从 src/messaging/error.ts 开始,阅读 THIRD_PARTY_AUTH_ERROR 映射以及后面的 error.message 赋值。确认存在原始 UNAUTHENTICATED 响应时如何选择规范的 APNs 消息,然后更新行为和措辞,使其涵盖 APNs 身份验证密钥和 Web Push VAPID 凭据。完成的标准是 third-party-auth-error 不再将误导性的原始 OAuth 指引作为主要消息显示。

由索引模型根据 Issue 内容生成。

评估

技术栈
typescript
领域
api, backend
Issue 类型
缺陷
难度
3/5
预计耗时
1-2 天
活跃度
冷清
描述清晰度
基本清楚
新手友好度
70/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。