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

Node.js+Firebase Functions环境下Apollo Client实例化报错求助

问题修复:Apollo Client在Node.js/Firebase Functions中实例化报错(Invariant Violation)

问题场景

在Node.js 16 + TypeScript + Firebase Functions后端环境中,实例化Apollo Client时触发如下错误:

{"message":{"framesToPop":1,"name":"Invariant Violation"}}

需求是通过Snapshot的GraphQL接口查询指定提案ID的投票数据,当前使用依赖版本:

  • @apollo/client: ^3.7.10
  • graphql: ^16.6.0

相关代码片段:

expressApp.post("/sample", async (req: any, res: any) => {
  try {
    const data = req.body;
    console.log(`===req.body data is ${data}===`);

    const scoreQuery = gql`
      query Proposal($proposal_id: String!) {
        proposal(id: $proposal_id) {
          state
          scores
        }
      }
    `;

    // 此处实例化时触发报错
    const apolloClient = new ApolloClient({
      uri: "https://hub.snapshot.org/graphql",
      cache: new InMemoryCache(),
    });
    // ...后续查询逻辑
  } catch (error) {
    // 错误处理
  }
});

报错原因

该错误主要源于两个核心问题:

  1. Node.js 16环境中缺少Apollo Client依赖的标准fetch实现(Apollo Client默认依赖浏览器环境的fetch)
  2. 每次请求都重复实例化Apollo Client,引发缓存或内部状态冲突

修复方案

1. 引入Node兼容的fetch实现

安装cross-fetch作为Node环境的fetch替代:

npm install cross-fetch
# 或使用yarn
yarn add cross-fetch

2. 使用全局单例Apollo Client

将Apollo Client实例化移到请求处理函数外部,避免重复创建实例,同时配置fetch:

修改后完整代码

import { ApolloClient, InMemoryCache, gql } from '@apollo/client';
import crossFetch from 'cross-fetch';
import express from 'express';

const expressApp = express();
expressApp.use(express.json());

// 全局单例Apollo Client,仅初始化一次
const apolloClient = new ApolloClient({
  uri: "https://hub.snapshot.org/graphql",
  cache: new InMemoryCache(),
  fetch: crossFetch, // 指定Node环境兼容的fetch
});

expressApp.post("/sample", async (req: any, res: any) => {
  try {
    const data = req.body;
    console.log(`===req.body data is ${JSON.stringify(data)}===`);

    const scoreQuery = gql`
      query Proposal($proposal_id: String!) {
        proposal(id: $proposal_id) {
          state
          scores
        }
      }
    `;

    // 执行查询
    const response = await apolloClient.query({
      query: scoreQuery,
      variables: { proposal_id: data.proposal_id },
      // 可选:若不需要缓存,可添加该配置
      // fetchPolicy: 'no-cache'
    });

    res.status(200).json(response.data);
  } catch (error) {
    console.error('查询异常:', error);
    res.status(500).json({ error: '查询投票数据失败' });
  }
});

额外优化建议

  • 确认Firebase Functions的Node.js版本配置为16(可在firebase.json或package.json中指定)
  • 若使用node-fetch替代cross-fetch,注意v3版本需使用ES模块导入,或改用v2版本

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 16:30:22