Gui*_*ost 9 firebase vue.js firebase-tools nuxt.js google-cloud-firestore
我几周前已更新到 Firebase v9,在尝试将我的 Firebase 应用程序连接到 Firestore 模拟器时遇到问题。
firebase.js(我的 VueJS 插件,我在其中设置 Firebase):
import { initializeApp, getApps } from "firebase/app"
import { getAuth, connectAuthEmulator, onAuthStateChanged } from "firebase/auth";
import { getFirestore, connectFirestoreEmulator } from "firebase/firestore"
import { getStorage, connectStorageEmulator } from "firebase/storage";
import { getFunctions, connectFunctionsEmulator } from 'firebase/functions';
import { isSupported, getAnalytics } from "firebase/analytics";
export default async ({ app }, inject) => {
const firebaseConfig = {
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_SERVICE_ID,
appId: process.env.FIREBASE_APP_ID,
measurementId: process.env.FIREBASE_MEASUREMENT_ID,
}
// I've checked, the values of firebaseConfig are all set here.
// This IF statement is here to avoid initializing the app several times
const apps = getApps();
let firebaseApp = null;
if (!apps.length) {
firebaseApp = initializeApp(firebaseConfig);
}
else {
firebaseApp = apps[0];
}
// INIT AUTH
const auth = getAuth();
auth.languageCode = 'fr';
onAuthStateChanged(auth, async authUser => {
const claims = authUser ? (await authUser.getIdTokenResult(true)).claims : null;
await app.store.dispatch('onAuthStateChanged', { authUser, claims });
},
(error) => {
console.error("Firebase Auth onAuthStateChanged ERROR", error)
});
// Get other services
const firestore = getFirestore(firebaseApp);
const storage = getStorage(firebaseApp);
const functions = getFunctions(firebaseApp, process.env.FIREBASE_REGION);
// Setup analytics if supported
let analytics = null;
const analyticsSupported = await isSupported()
if (analyticsSupported) {
analytics = getAnalytics();
analytics.automaticDataCollectionEnabled = false;
}
// Connecting to emulators
if (process.client && process.env.APP_ENV === 'local') {
console.log("LOCAL ENVIRONMENT, CONNECTING TO EMULATORS...");
connectAuthEmulator(auth, "http://localhost:9099");
connectFirestoreEmulator(firestore, 'localhost', 8080);
connectStorageEmulator(storage, "localhost", 9199);
connectFunctionsEmulator(functions, "localhost", 5001);
}
Inject firebase objects into my VueJS app
const fire = { auth, firestore, storage, functions, analytics }
inject('fire', fire);
}
Run Code Online (Sandbox Code Playgroud)
这是我得到的错误,由这一行引起:connectFirestoreEmulator(firestore, 'localhost', 8080);
FirebaseError Firestore 已启动,无法再更改其设置。您只能在调用 Firestore 对象上的任何其他方法之前修改设置。
我不想settings自己修改 Firestore 对象的属性,所以它必须是 method connectFirestoreEmulator。
问题可以缩小到以下代码:
import { initializeApp } from "firebase/app"
import { getFirestore, connectFirestoreEmulator } from "firebase/firestore"
export default async ({ app }, inject) => {
const firebaseConfig = {
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_SERVICE_ID,
appId: process.env.FIREBASE_APP_ID,
measurementId: process.env.FIREBASE_MEASUREMENT_ID,
}
firebaseApp = initializeApp(firebaseConfig);
const firestore = getFirestore(firebaseApp);
if (process.env.APP_ENV === 'local') {
connectFirestoreEmulator(firestore, 'localhost', 8080);
}
const fire = { auth, firestore, storage, functions, analytics };
inject('fire', fire);
}
Run Code Online (Sandbox Code Playgroud)
我设法通过添加来避免触发错误process.client,因此它不会连接到服务器端(SSR)上的模拟器:
if (process.client && process.env.APP_ENV === 'local') {
Run Code Online (Sandbox Code Playgroud)
然而,当我添加这一点时,当在第一页加载时在服务器端(SSR)执行代码时,模拟器不会连接,并且初始 Firestore 数据是从真正的 Firebase 应用程序而不是模拟器中读取的。
知道如何管理 SSR 上与 Firestore 模拟器的正确连接吗?
这是 Firebase 错误吗?
我使用的版本:
我已经读过/尝试过的内容:
小智 8
已经有一段时间了,但我遇到了类似的问题,经过一番折腾后,我最终找到了一个解决方案(尽管感觉有点老套)。
在运行 connectFirestoreEmulator 行之前,检查 firestor._settingsFrozen 是否为 false。因此,基本上只有在 Firestore 尚未初始化时才运行该行。您可以通过在 connectFirestoreEmulator 行之前注销 firestore 变量并查看其中的设置内容来检查 firestore 是否已使用模拟器设置进行初始化 - 如果它显示端口是 8080 并且主机是 localhost,那么就可以了。
这是我的比较代码(与您的设置略有不同,但我相信我们遇到了同样的问题):
import { initializeApp } from 'firebase/app';
import { connectAuthEmulator, getAuth } from 'firebase/auth';
import { connectFirestoreEmulator, getFirestore } from 'firebase/firestore';
const firebaseConfig = {
apiKey: "XXXXXXXXX",
authDomain: "XXXXXXXXX",
projectId: "XXXXXXXXX",
storageBucket: "XXXXXXXXX",
messagingSenderId: "XXXXXXXXX",
appId: "XXXXXXXXX",
measurementId: "XXXXXXXXX",
};
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
export const db = getFirestore(app);
export default (context) => {
if (context.env.appEnv === 'dev') {
connectAuthEmulator(auth, `http://127.0.0.1:${context.env.authPort}`);
if (!db._settingsFrozen) {
connectFirestoreEmulator(db, '127.0.0.1', parseInt(context.env.firestorePort));
}
}
}
Run Code Online (Sandbox Code Playgroud)
查看Firebase JS SDK相关问题,该问题似乎是因为 Firestore 实例(如下初始化:)firestore = getFirestore(firebaseApp)是在模拟器(connectFirestoreEmulator)启动后调用的。
调用"connectFirestoreEmulator"方法后,"firestore"变量正在常量变量中使用"fire = { auth, firestore, storage, functions, analytics }"
如果在连接模拟器之前使用“const fire”,问题可能会得到解决。
这是一个可能对您有帮助的代码示例:
firebaseApp = initializeApp(firebaseConfig);
const fire = { auth, firestore, storage, functions, analytics };
const firestore = getFirestore(firebaseApp);
if (process.env.APP_ENV === 'local') {
connectFirestoreEmulator(firestore, 'localhost', 8080);
}
Run Code Online (Sandbox Code Playgroud)
作为参考,我使用了这个github 存储库。
| 归档时间: |
|
| 查看次数: |
5566 次 |
| 最近记录: |