如何在Firebase中将GraphQL封装为onCall可调用函数及实现方法
完全可以使用Firebase的onCall可调用函数承载GraphQL服务,刚好可以复用可调用函数内置的身份鉴权能力,无需自行解析token获取用户信息。
服务端代码改造
改造核心逻辑:不需要再使用express和express-graphql中间件,直接调用GraphQL原生的执行方法处理请求即可,原有Schema定义可以完全复用:
const functions = require("firebase-functions"); const { graphql } = require('graphql'); const { GraphQLObjectType, GraphQLString, GraphQLSchema, GraphQLID, GraphQLNonNull } = require('graphql'); // 原有的Schema定义完全不需要改动 const RootQuery = new GraphQLObjectType({ name: 'Query', fields: { tournament: { type: GraphQLString, args: { id: { type: GraphQLNonNull(GraphQLID) } }, resolve(parentValue, args, context) { // 这里的context就是Firebase可调用函数的上下文对象 // 可以直接取context.auth.uid获取当前登录用户id,无需自行鉴权 return `Some result for id: ${args.id}, 操作用户uid: ${context.auth?.uid}` } }, } }) const schema = new GraphQLSchema({ query: RootQuery }) // 替换原来的onRequest导出为onCall exports.graphql = functions.https.onCall(async (data, context) => { // 接收客户端传递的GraphQL参数 const { query, variables, operationName } = data; // 执行GraphQL查询,把Firebase的context作为上下文传入resolve const result = await graphql({ schema: schema, source: query, rootValue: root, // 如果你原有逻辑有自定义root对象,保留这行即可 contextValue: context, variableValues: variables, operationName: operationName }); return result; });
客户端调用方法
直接使用Firebase SDK提供的httpsCallable方法调用即可,参数和普通GraphQL请求参数格式一致,Web端示例如下:
import { initializeApp } from "firebase/app"; import { getFunctions, httpsCallable } from "firebase/functions"; // 初始化Firebase,你原有项目的初始化逻辑不用修改 const app = initializeApp({ // 你的Firebase项目配置 }); const functions = getFunctions(app); // 绑定我们部署的graphql可调用函数 const callGraphQL = httpsCallable(functions, 'graphql'); // 发起GraphQL查询 const fetchTournament = async (tournamentId) => { const { data } = await callGraphQL({ // GraphQL查询语句 query: ` query GetTournament($id: ID!) { tournament(id: $id) } `, // 查询变量 variables: { id: tournamentId } }); // 返回的data格式和普通GraphQL返回一致,包含data和errors字段 if (data.errors) { console.error('查询失败', data.errors); return; } console.log('查询结果', data.data.tournament); }
注意事项
- 原有的
graphiql调试工具无法继续使用,因为onCall遵循Firebase可调用函数专有协议,不兼容普通HTTP的GraphQL调试请求,可以通过Firebase控制台的函数日志查看请求参数和返回结果。 - 所有Resolver函数的第三个参数就是Firebase可调用函数的完整上下文,你可以直接读取
context.auth判断用户登录状态、获取用户UID等信息,完全不需要自行处理JWT鉴权逻辑。 - Mutation操作和Query操作使用方式完全一致,只需把客户端传入的
query字段替换为mutation语句即可。
内容的提问来源于stack exchange,提问作者Eggon
相关产品推荐
相关产品推荐

