NextJS环境变量无法正常工作。

8

我已经钻研了至少一个小时,但是目前我还没有头绪。也许我没有理解文档或媒体文章的意思。但是,据我所知,NextJS(我安装了最新版本)提供了内置的env变量解决方案。因此,不需要使用dotenv包。

由于NextJS已经设置好了,我只需要创建一个env.local来存储我的API_KEY和其他敏感信息。然后,一旦我保存了更新后的文件,我就可以在代码中的任何地方访问${process.env.API_KEY}并访问该值。

假设以上陈述是正确的,我仍无法使其工作。

在我的情况下,我正在使用环境变量连接Firebase。下面的代码实现了它。我收到了500个格式错误的错误消息:

Connection GRPC stream error. Code: 3 Message: 3 INVALID_ARGUMENT: 
Project id parakeat-a1-7706, is malformed: it either contains invalid 
characters or is too long. Look at https://cloud.google.com
/resource-manager/docs/creating-managing-projects#identifying_projects 
for instructions in how to get a project's id.

import * as firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';
import 'firebase/storage';
import 'firebase/analytics';

const config = {
  apiKey: process.env.FIREBASE_API_KEY,
  authDomain: process.env.FIREBASE_AUTH_DOMAIN,
  databaseURL: process.env.FIREBASE_DATABASE_URL,
  projectId: process.env.FIREBASE_PROJECT_ID,
  storageBucket: process.env.FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID,
  appId: process.env.FIREBASE_APP_ID,
  measurementId: process.env.FIREBASE_MEASUREMENT_ID,
};
// Initialize Firebase
try {
  firebase.initializeApp(config);
} catch (err) {
  // we skip the "already exists" message which is
  // not an actual error when we're hot-reloading
  if (!/already exists/.test(err.message)) {
    console.error('Firebase initialization error', err.stack);
  }
}

// const firebaseAnalytics = firebase.analytics();
const firebaseStorage = firebase.storage();
const firebaseFirestore = firebase.firestore();

export { firebaseStorage, firebaseFirestore };

上面正确显示了ID,那么问题出在哪里呢?为什么如果我直接把实际值放进去跳过process.env的话就能成功连接呢?
2个回答

18

默认情况下,通过.env.local加载的所有环境变量仅在Node.js环境中(例如在getStaticProps方法中)可用,这意味着它们不会暴露给浏览器。

要将变量暴露给浏览器,您必须使用NEXT_PUBLIC_前缀。例如:

NEXT_PUBLIC_ANALYTICS_ID=abcdefghijk

文档


1
嗯,我相信添加 NEXT_PUBLIC ... 前缀也会导致给定的环境变量暴露给客户端。这对于 API_KEYS 和其他我们想要保护的信息来说是不好的。 - kevin
5
Firebase提供给你的Web配置文件是用于客户端使用的。请参考此问题。对于在客户端和服务器端都要使用的环境变量,请添加NEXT_PUBLIC前缀。对于仅在服务器端使用的环境变量,请不要添加前缀。 - hangindev.com
2
啊,非常感谢您的帮助。这样就更清晰了,所以在这种情况下,我不需要处理所有这些值的 process.env。关于您最后的评论,我认为您的陈述有矛盾之处。“对于客户端和服务器端都要使用的环境变量,请添加 NEXT_PUBLIC 前缀。对于仅在服务器端使用的环境变量,请不要添加前缀。”“您不希望该私钥在客户端中被泄露,这意味着您应该为该密钥添加 NEXT_PUBLIC 前缀。”这是一个打字错误吗? - kevin
1
没错,那是个打字错误。我会将其删除,以免混淆他人。这就是我的意思:Firebase 还为您提供了一个私钥,供您使用 Firebase Admin SDK。您不希望该私钥在客户端中被泄露,这意味着您不应该为该密钥添加 NEXT_PUBLIC 前缀。 - hangindev.com
你好。我正在尝试在这里做完全相同的事情。我有我的firebaseConfig.js文件和密钥。我创建了一个名为env.local的文件,其中包含我的秘密内容。并使用与上面问题顶部所述的相同语法设置了配置对象。问题是我收到了一个错误消息FIREBASE FATAL ERROR: Can't determine Firebase Database URL. Be sure to include a Project ID when calling firebase.initializeApp() - Arp
显示剩余2条评论

0

我之前使用过上述解决方案,但后来需要将我的.env变量包含在捆绑文件中,这就是为什么我使用next.config.js文件来存放我的变量的原因。

请参考他们文档中的此链接:

Nextjs - next.config.js


文档中说,在版本 9.4 之后,有一个内置的解决方案可以实现我上面尝试的操作。它说使用 .env.local 将会向我的应用程序公开这些变量。嗯... - kevin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接