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

Firebase signInWithCustomToken 随机触发‘failed to fetch’错误且1小时内无法恢复的问题求助

Firebase signInWithCustomToken 随机触发‘failed to fetch’错误且1小时内无法恢复的问题求助

大家好,我这边遇到一个非常棘手的随机问题,折腾了好久都没找到原因,想请各位帮忙排查一下:

环境信息

  • 操作系统:Mac OS X >=10.15.7、Windows >=10
  • 浏览器:Chrome、Safari、Firefox
  • 依赖版本:
    • Firebase SDK ^12.1.0(仅使用Auth模块)
    • Next.js 14 + TypeScript
    • Clerk 客户端认证组件
    • Firebase Auth 配置为内存持久化(为了避免IndexedDB相关问题)

问题详细描述

我们的业务逻辑是通过Clerk获取Firebase自定义token,调用signInWithCustomToken完成认证后访问Firestore。但有大概5%的用户会随机遇到以下问题:

  1. 调用signInWithCustomToken后,函数会无响应挂起30秒,然后抛出failed to fetch错误
  2. 一旦触发这个错误,该用户在接下来的1小时左右时间里,完全无法通过这个函数完成认证——但同一个token在其他设备/浏览器上却能正常登录

我们的认证流程是严谨的:

  • 先确认Clerk会话有效,获取到合法的Firebase自定义token(已经和Clerk团队确认过token本身是有效的)
  • 等待Firebase Auth的authStateReady()完成(用了内存持久化)
  • 确保所有前置条件(isLoaded/isSignedIn/user都为true,无竞态条件)满足后,才调用signInWithCustomToken

已经排除的可能性

我们逐一排查了所有可能的环节,确认以下部分完全正常:

1. Firebase Auth初始化无问题

  • getBrowserAuth()能稳定返回Auth实例
  • auth.authStateReady()能正常完成,无超时
  • Auth状态能正常读取,不存在未初始化的情况

2. Token生成与验证完全合法

  • 调用getToken({ template: 'integration_firebase' })始终返回非空token
  • Token验证通过,无空值或格式错误
  • Clerk会话处于活跃有效状态,Clerk团队已确认token本身完全合法
  • 同一个token在其他设备/浏览器上能100%正常完成登录

3. 所有前置条件都已满足

  • isLoaded && isSignedIn && user均为true
  • isFirebaseAuthReady为true(Auth监听器已成功建立)
  • 通过!isAuthenticating状态严格避免了竞态条件

4. 错误触发的奇怪规律

  • 错误只会在调用signInWithCustomToken时稳定触发,其他环节无异常
  • 触发错误时,Firebase Auth实例存在且已初始化,token也完全有效
  • 最诡异的是:触发错误时没有任何网络请求发出——哪怕我们已经把持久化模式设为内存模式,按道理应该直接发起请求才对

相关代码片段

核心认证逻辑

import { useAuth } from '@clerk/nextjs';
import { auth } from '@/lib/firebase';
import { signInWithCustomToken } from 'firebase/auth';

const performAuth = async () => {
  const { getToken, isLoaded, isSignedIn, userId } = useAuth();

  // 等待Clerk加载完成
  if (!isLoaded || !isSignedIn || !userId) {
    return false;
  }

  try {
    // 从Clerk获取Firebase自定义token
    const token = await getToken({ template: 'integration_firebase' });
    if (!token) {
      throw new Error('Token unavailable');
    }

    // 就是这行会挂起30秒后抛出failed to fetch错误
    const credentials = await signInWithCustomToken(auth, token);
    return !!credentials.user;
  } catch (err) {
    throw new Error('Authentication failed');
  }
};

Firebase Auth Provider 核心初始化代码

'use client';
import { createContext, useContext, useEffect, useState } from 'react';
import { useAuth, useUser } from '@clerk/nextjs';
import { onAuthStateChanged, getAuth, initializeAuth, inMemoryPersistence, type Auth } from 'firebase/auth';
import { app } from '@/lib/firebase';
import * as Sentry from '@sentry/nextjs';

let authSingleton: Auth | null = null;

export function getBrowserAuth(): Auth {
  if (typeof window === 'undefined') {
    throw new Error('getBrowserAuth can only be called on the client side');
  }
  if (!authSingleton) {
    try {
      // 用内存持久化初始化Auth
      authSingleton = initializeAuth(app, { persistence: inMemoryPersistence });
    } catch {
      // 重复初始化时回退到getAuth
      authSingleton = getAuth(app);
    }
  }
  return authSingleton;
}

interface FirebaseAuthContextType {
  isFirebaseAuthenticated: boolean;
  firebaseAuthError: Error | null;
  isAuthenticating: boolean;
  isFirebaseAuthReady: boolean;
  firebaseAuth: Auth | null;
}

const FirebaseAuthContext = createContext<FirebaseAuthContextType | undefined>(undefined);

const FIREBASE_AUTH_TIMEOUT = 3000;
const FIREBASE_SETUP_TIMEOUT = 5000;

export function FirebaseAuthProvider({ children }: { children: React.ReactNode }) {
  const { isSignedIn, user } = useUser();
  const { getToken, isLoaded } = useAuth();
  const [isFirebaseAuthenticated, setIsFirebaseAuthenticated] = useState(false);
  const [firebaseAuthError, setFirebaseAuthError] = useState<Error | null>(null);
  const [isAuthenticating, setIsAuthenticating] = useState(false);
  const [isFirebaseAuthReady, setIsFirebaseAuthReady] = useState(false);

  // 剩余的Provider监听与认证逻辑省略,核心初始化逻辑如上
  // ...
}

求助疑问

现在完全搞不懂为什么这个错误会随机出现,而且出现后会持续1小时左右。已经排除了token、初始化、网络环境这些常见问题,甚至连网络请求都没发出来就报错了。

想请教各位:有没有遇到过类似问题?或者Firebase Auth有没有什么我们没考虑到的机制(比如某种隐性限流?内存持久化下的隐藏状态问题?)可以指点一下排查方向?

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 08:18:06