英文:
Why can't I fetch data from Firebase in my React.js app? (error: db.collection is not a function)
问题
I desire to fetch data from my Firestore and display it in my React.js component. The problem is that every time I click on the button that is supposed to fetch data, I receive the following error: Uncaught TypeError: db.collection is not a function (FetchedData.jsx:15).
Does anyone know why and how this can be fixed?
Thanks in advance!
Here is the component:
import { useState, useEffect } from "react";
import { db } from "../../firebase";
const Fetch = () => {
const [allDocs, setAllDocs] = useState([]);
const [singleDoc, setSingleDoc] = useState({});
const fetchAll = (e) => {
db.collection("f_Collections")
.get()
.then((snapshot) => {
if (snapshot.docs.length > 0) {
snapshot.docs.forEach((doc) => {
setAllDocs((prev) => {
return [...prev, doc.data()];
});
});
}
});
console.log(allDocs);
};
return (
<div className="">
qwerty
<button type="button" onClick={fetchAll} className="">
Fetch
</button>
</div>
);
};
export default Fetch;
Here is my Firebase config file:
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
import { getFirestore } from "firebase/firestore";
import "firebase/firestore";
import * as firebase from "firebase/app";
const firebaseConfig = {
apiKey: "-",
authDomain: "give-authorization.firebaseapp.com",
projectId: "give-authorization",
storageBucket: "give-authorization.appspot.com",
messagingSenderId: "-",
appId: "-"
};
const foundationsConfig = {
apiKey: "-",
authDomain: "give-foundationsorganization.firebaseapp.com",
projectId: "give-foundationsorganization",
storageBucket: "give-foundationsorganization.appspot.com",
messagingSenderId: "-",
databaseURL: "",
appId: "-"
};
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
const foundationsApp = initializeApp(foundationsConfig, "foundations");
export const db = getFirestore(foundationsApp);
Important keys and API have been replaced with "-" but the source code has actual data.
英文:
I desire to fetch data from my Firestore and display it in my React.js component. The problem is that every time I click on the button that is supposed to fetch data, I receive the following error:
Uncaught TypeError: db.collection is not a function (FetchedData.jsx:15).
Does anyone know why and how this can be fixed?
Thanks in advance!
Here is the component that:
import { useState, useEffect } from "react";
import { db } from "../../firebase";
const Fetch = () => {
const [allDocs, setAllDocs] = useState([]);
const [singleDoc, setSingleDoc] = useState({});
// const db = firebase.firestore(); //-tak to powinno wyglądać, ale wywala błąd firebase.firestore() is not a function
// const db = firebase.firestore();
const fetchAll = (e) => {
db.collection("f_Collections")
.get()
.then((snapshot) => {
if (snapshot.docs.length > 0) {
snapshot.docs.forEach((doc) => {
setAllDocs((prev) => {
return [...prev, doc.data()];
});
});
}
});
console.log(allDocs);
};
return (
<div className="">
qwerty
<button type="button" onClick={fetchAll} className="">
Fetch
</button>
</div>
);
};
export default Fetch;
Here is my Firebase config file
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
import { getFirestore } from "firebase/firestore";
import "firebase/firestore";
import * as firebase from "firebase/app";
const firebaseConfig = {
apiKey: "-",
authDomain: "give-authorization.firebaseapp.com",
projectId: "give-authorization",
storageBucket: "give-authorization.appspot.com",
messagingSenderId: "-",
appId: "-"
};
const foundationsConfig = {
apiKey: "-",
authDomain: "give-foundationsorganization.firebaseapp.com",
projectId: "give-foundationsorganization",
storageBucket: "give-foundationsorganization.appspot.com",
messagingSenderId: "-",
databaseURL: "",
appId: "-"
};
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
const foundationsApp = initializeApp(foundationsConfig, "foundations");
export const db = getFirestore(foundationsApp);
Impornant keys and API have been replaced with "-" but the sourcecode has actual data.
答案1
得分: 1
这是如何初始化你的两个 Firebase 项目的方法。只需确保以下代码在你可以使用组件之前的某个地方被初始化。我不了解 React,但下面的代码最适合在加载任何组件之前触发的某个插件/扩展中使用。
import { initializeApp } from "firebase/app";
const firebaseConfig = {
apiKey: "-",
authDomain: "give-authorization.firebaseapp.com",
projectId: "give-authorization",
storageBucket: "give-authorization.appspot.com",
messagingSenderId: "-",
appId: "-"
};
const foundationsConfig = {
apiKey: "-",
authDomain: "give-foundationsorganization.firebaseapp.com",
projectId: "give-foundationsorganization",
storageBucket: "give-foundationsorganization.appspot.com",
messagingSenderId: "-",
databaseURL: "",
appId: "-"
};
initializeApp(firebaseConfig);
initializeApp(foundationsConfig, "foundations");
以下是你的组件应该如何看起来的示例。
import { useState, useEffect } from "react";
import { getDoc, doc, getFirestore, getApp } from "@firebase/firestore";
const Fetch = () => {
const [allDocs, setAllDocs] = useState([]);
const [singleDoc, setSingleDoc] = useState({});
const fetchAll = async (e) => {
const result = await getDoc(doc(getFirestore(getApp('foundations')), 'f_collections'))
if(result.exists) {
result.data.forEach(docSnap => {
setAllDocs(prev => [...prev, docSnap.data()])
})
}
console.log(allDocs);
};
return (
<div className="">
qwerty
<button type="button" onClick={fetchAll} className="">
Fetch
</button>
</div>
);
};
export default Fetch;
这是你应该使用函数式方法编程的方式,在 Firebase V9 中。你的控制台日志在 .then
范围之外。在我的示例中,我使用了 async/await
方式。使用这种方法,你可以减少大量的“样板代码”。如果你使用我的代码,结果将存储在 allDocs
变量中。如果你想使用你的代码获得结果,你需要将 console.log(allDocs)
移到 .then
方法内部。
英文:
This is how you should initialize your both Firebase projects. Just make sure code below will be initialized somewhere before you can use components. I don't know react, but the best fit for code below is some plugin/extension that will be triggered before any components can be loaded.
import { initializeApp } from "firebase/app";
const firebaseConfig = {
apiKey: "-",
authDomain: "give-authorization.firebaseapp.com",
projectId: "give-authorization",
storageBucket: "give-authorization.appspot.com",
messagingSenderId: "-",
appId: "-"
};
const foundationsConfig = {
apiKey: "-",
authDomain: "give-foundationsorganization.firebaseapp.com",
projectId: "give-foundationsorganization",
storageBucket: "give-foundationsorganization.appspot.com",
messagingSenderId: "-",
databaseURL: "",
appId: "-"
};
initializeApp(firebaseConfig);
initializeApp(foundationsConfig, "foundations");
And here how your component should look like.
import { useState, useEffect } from "react";
import { getDoc, doc, getFirestore, getApp } from "@firebase/firestore"
const Fetch = () => {
const [allDocs, setAllDocs] = useState([]);
const [singleDoc, setSingleDoc] = useState({});
const fetchAll = async (e) => {
const result = await getDoc(doc(getFirestore(getApp('foundations')), 'f_collections'))
if(result.exists) {
result.data.forEach(docSnap => {
setAllDocs(prev => [...prev, docSnap.data()])
})
}
console.log(allDocs);
};
return (
<div className="">
qwerty
<button type="button" onClick={fetchAll} className="">
Fetch
</button>
</div>
);
};
export default Fetch;
This is how you should program using functional approach way, in Firebase V9.
Your console log was out of a .then
scope. In my example, I made it using async/await
way. Using this approach, you're removing a lot of "boilerplate code". If you use my code, it will have a result in allDocs
variable. If you want to have result using your code, you need to move console.log(allDocs)
inside .then
method.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论