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

解决Firebase Cloud Functions(Next.js实验性托管)权限问题

Next.js on Firebase Hosting(Experimental): Auth Redirect & Firestore Forbidden Error with Auto-Created Cloud Functions

核心问题梳理

  • 基于Firebase实验性Web框架支持部署Next.js应用,Firebase CLI自动生成了Cloud Function
  • 访问需读取Firestore数据的页面时,自动跳转到认证页;完成Google账号认证后返回禁止错误,且自动登出,重试时因已登出触发其他异常
  • 尝试给Cloud Function添加allUsers权限失败,报错:Error: Principals of type allUsers and allAuthenticatedUsers cannot be added to this resource;且本身不想开启该权限(Firestore安全规则已配置仅认证用户可读取数据)
  • 相同应用在Netlify部署(通过Next.js插件自动创建Edge Functions)时运行正常

问题原因分析

  1. Cloud Function认证上下文丢失
    Firebase自动创建的Next.js服务端函数(如nextjs-server)默认可能未配置传递用户认证令牌到Firestore请求,导致Firestore安全规则判定用户未认证,返回403错误,进而触发前端的认证跳转逻辑,甚至引发自动登出。

  2. Cloud Function IAM权限限制
    自动生成的这类函数属于Firebase托管绑定的特殊资源,不允许直接添加allUsers/allAuthenticatedUsers主体权限,这类请求必须通过Firebase Hosting的路由通道访问,而非直接给函数配置IAM权限。

  3. Next.js服务端请求的认证传递问题
    在SSR/ISR场景下,前端的认证状态未正确传递到服务端函数,导致服务端访问Firestore时无有效身份凭证。

解决方案步骤

1. 在服务端函数中正确传递并验证用户认证

在Next.js的getServerSideProps或getStaticProps(ISR场景)中,从请求Cookie获取Firebase Auth的ID Token并验证,确保用合法身份访问Firestore:

import { getAuth, verifyIdToken } from "firebase-admin/auth";
import admin from "firebase-admin";

// 初始化Firebase Admin(确保只执行一次)
if (!admin.apps.length) {
  admin.initializeApp();
}

export async function getServerSideProps(context) {
  // 从Cookie获取Firebase Auth默认存储的ID Token
  const idToken = context.req.cookies.__session;
  let user = null;

  if (idToken) {
    try {
      // 验证Token合法性
      const decodedToken = await verifyIdToken(idToken);
      user = decodedToken;
    } catch (error) {
      // Token验证失败,重定向到认证页
      return {
        redirect: {
          destination: "/auth",
          permanent: false,
        },
      };
    }
  } else {
    // 无Token,重定向到认证页
    return {
      redirect: {
        destination: "/auth",
        permanent: false,
      },
    };
  }

  // 用验证后的用户身份访问Firestore
  const db = admin.firestore();
  const dataSnapshot = await db.collection("your-collection")
    .where("uid", "==", user.uid)
    .get();

  return {
    props: {
      data: dataSnapshot.docs.map(doc => doc.data())
    }
  };
}

同时在前端登录后,确保将ID Token写入__session Cookie,以便服务端能获取到:

import { getAuth, onAuthStateChanged } from "firebase/auth";

const auth = getAuth();
onAuthStateChanged(auth, async (user) => {
  if (user) {
    const idToken = await user.getIdToken();
    // 设置Cookie,确保跨请求传递
    document.cookie = `__session=${idToken}; path=/; secure; sameSite=Strict`;
  } else {
    // 登出时清除Cookie
    document.cookie = "__session=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
  }
});

2. 验证Firebase Hosting重写规则

检查firebase.json中的重写规则,确保所有Next.js请求(包括SSR、Image API)都正确路由到自动创建的函数:

{
  "hosting": {
    "public": "out",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "**",
        "function": "nextjs-server" // 替换为你实际的自动生成函数名称,可在Firebase控制台Functions页面查看
      }
    ]
  }
}

3. 检查Firestore安全规则逻辑

确认安全规则正确判断用户认证状态,比如基础的认证用户读写规则:

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

如果是更细粒度的权限控制(如仅允许用户访问自己的数据),确保request.auth.uid与文档中的uid字段匹配,避免逻辑错误。

4. 排查Cloud Function执行日志

到Firebase控制台的Cloud Functions页面,找到自动生成的函数,查看执行日志,定位具体错误原因(比如ID Token验证失败、Firestore权限拒绝的详细信息)。

5. 升级Firebase CLI并确认实验性功能状态

由于使用的是实验性功能,确保CLI为最新版本并启用了Web框架支持:

# 检查CLI版本
firebase --version
# 升级到最新版
npm install -g firebase-tools
# 确认实验性功能已启用
firebase experiments:enable webframeworks

内容的提问来源于stack exchange,提问作者Bolaji Ayodeji

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 04:20:29