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

Firebase Functions模拟器权限拒绝:如何允许未认证调用?

问题描述

我正尝试通过Expo Go应用调用Firebase云函数,当前使用Firestore和Functions模拟器(通过firebase emulators:start启动)。

我的云函数代码如下:

import * as functions from "firebase-functions";
 export const helloWorld = functions.https.onRequest((request, response) => {
   response.send({"text":"Hello from Firebase!"});
 });

Expo Go应用中的调用代码:

import { StyleSheet, Text, View } from 'react-native';
import {initializeApp} from 'firebase/app';
import {getFirestore, connectFirestoreEmulator } from "firebase/firestore";
import {getFunctions, connectFunctionsEmulator, httpsCallable} from "firebase/functions";
import {useState} from "react";
initializeApp({
  apiKey: "AIzxxxxxxxxxxxxxxxxxxxBbBFNGMI",
  authDomain: "sixxxxxxxxxcc8.firebaseapp.com",
  projectId: "sxxxxxxxxxxx8",
  storageBucket: "xxxxxxxxxxxxxcc8.appspot.com",
  messagingSenderId: "6xxxxxxxxxx",
  appId: "1:65xxxxxxxx13:web:d0exxxxxxxxxxxxxxxxx7c"
});
const db = getFirestore();
const functions = getFunctions();
  connectFirestoreEmulator(db, "localhost", 8080 )
  connectFunctionsEmulator(functions, "localhost", 5000 )

const addMessage = httpsCallable(functions, 'helloWorld');
export default function App() {
  const [result, setResult] = useState("")
  addMessage({ text: "text" })
      .then((result) => {
        // Read result of the Cloud Function.
        /** @type {any} */
        const data = result.data;
        const sanitizedMessage = data.text;
        setResult(sanitizedMessage)
      }).catch(console.log);
  return (
    <View style={styles.container}>
      <Text>{result}</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

但始终收到FirebaseError: permission-denied错误,推测是未认证导致的,请教如何在模拟器中禁用认证要求?

解决方案

核心问题说明

首先注意:你前端用httpsCallable调用的云函数,后端用的是functions.https.onRequest定义,这两种调用方式不匹配!httpsCallable需要对应onCall类型的云函数,这可能是触发权限错误的核心原因之一,先修正这个匹配问题,再处理模拟器认证。

1. 修正云函数类型为onCall,并跳过模拟器认证

修改云函数代码,判断当前是否处于模拟器环境,若是则直接允许访问:

import * as functions from "firebase-functions";

export const helloWorld = functions.https.onCall((data, context) => {
  // 模拟器环境下跳过认证检查
  if (process.env.FUNCTIONS_EMULATOR === "true") {
    return { "text": "Hello from Firebase!" };
  }

  // 生产环境可添加认证逻辑(按需保留)
  // if (!context.auth) {
  //   throw new functions.https.HttpsError('unauthenticated', '用户未登录');
  // }
  
  return { "text": "Hello from Firebase!" };
});

2. 若坚持使用onRequest函数(不推荐前端直接调用)

如果要保留onRequest类型的函数,可在代码中直接绕过模拟器的认证:

import * as functions from "firebase-functions";

export const helloWorld = functions.https.onRequest((request, response) => {
  // 模拟器环境直接响应
  if (process.env.FUNCTIONS_EMULATOR === "true") {
    response.send({ "text": "Hello from Firebase!" });
    return;
  }

  // 生产环境的认证逻辑(比如检查请求头中的认证信息)
  // ... 你的生产环境认证代码
  
  response.send({ "text": "Hello from Firebase!" });
});

此时前端调用方式需改为普通的fetch请求,而非httpsCallable,比如:

fetch('http://localhost:5000/your-project-id/us-central1/helloWorld', {
  method: 'POST',
  body: JSON.stringify({ text: "text" })
})
.then(res => res.json())
.then(data => setResult(data.text))
.catch(console.log);

额外注意事项

  • 确保firebase emulators:start正常启动,Functions模拟器端口为5000
  • Expo Go运行在真机上时,localhost需替换为电脑的局域网IP(比如192.168.x.x),否则无法访问本地模拟器

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 10:30:53