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
- 主要语言
- 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