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

如何在SSR期间使用手动验证的令牌执行Firestore查询?

问题

我希望在服务器端渲染(SSR)期间从Firestore获取数据。我知道可以用REST API(附加令牌到请求头),但不想在服务器端写REST请求,之后又在客户端用标准Firestore查询重复相同逻辑。客户端偏好标准查询(而非REST),因为它支持实时更新,同时我希望在服务器端也能复用客户端的查询(即使没有实时更新的优势)。

我在服务器端已手动验证令牌:

import admin from 'firebase-admin';
import { initializeApp, getApp } from 'firebase/app';
import { getFirestore } from 'firebase/firestore';

const firebaseApp = initializeApp(config);
const db = getFirestore(firebaseApp);

const decodedIdToken = await admin.auth().verifySessionCookie(sessionCookie);
// 令牌验证通过:decodedIdToken.userId = "xxx"

但执行查询时出现错误:

import { collection, getDocs } from 'firebase/firestore';

const querySnapshot = await getDocs(collection(db, 'myCollection'));

错误信息:

{
  "code": "permission-denied",
  "name": "FirebaseError"
}

Firestore规则:

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth != null;
    }
  }
}

客户端可以通过onAuthStateChanged解决该错误,但服务器端无法使用此监听器。请问是否有办法使用手动验证的令牌运行Firestore查询?


解决方案

你可以通过自定义令牌登录的方式,让服务器端的Firestore客户端SDK带上已验证用户的身份信息,步骤如下:

  1. 基于已验证的用户ID生成自定义令牌
    用Firebase Admin SDK为已验证的decodedIdToken.userId生成自定义令牌:

    const customToken = await admin.auth().createCustomToken(decodedIdToken.userId);
    
  2. 在服务器端的客户端SDK中登录该用户
    导入Firebase Auth的客户端方法,使用自定义令牌完成登录:

    import { getAuth, signInWithCustomToken } from 'firebase/auth';
    
    const auth = getAuth(firebaseApp);
    await signInWithCustomToken(auth, customToken);
    
  3. 执行Firestore查询
    登录完成后,再执行你的查询,此时请求会带上有效的request.auth信息,符合Firestore规则的要求:

    const querySnapshot = await getDocs(collection(db, 'myCollection'));
    

这种方式既复用了客户端的Firestore查询逻辑,又让服务器端的请求通过了权限验证,不需要单独编写REST请求。


内容的提问来源于stack exchange,提问作者Petr K.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 20:05:24