Why can't I fetch data from Firebase in my React.js app? (error: db.collection is not a function)

huangapple go评论56阅读模式
英文:

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 &quot;react&quot;;
import { db } from &quot;../../firebase&quot;;

const Fetch = () =&gt; {
  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) =&gt; {
    db.collection(&quot;f_Collections&quot;)
      .get()
      .then((snapshot) =&gt; {
        if (snapshot.docs.length &gt; 0) {
          snapshot.docs.forEach((doc) =&gt; {
            setAllDocs((prev) =&gt; {
              return [...prev, doc.data()];
            });
          });
        }
      });
    console.log(allDocs);
  };

   return (
    &lt;div className=&quot;&quot;&gt;
      qwerty
      &lt;button type=&quot;button&quot; onClick={fetchAll} className=&quot;&quot;&gt;
        Fetch
      &lt;/button&gt;
    &lt;/div&gt;
  );
};

export default Fetch;

Here is my Firebase config file

import { initializeApp } from &quot;firebase/app&quot;;
import { getAuth } from &quot;firebase/auth&quot;;
import { getFirestore } from &quot;firebase/firestore&quot;;
import &quot;firebase/firestore&quot;;
import * as firebase from &quot;firebase/app&quot;;

const firebaseConfig = {
  apiKey: &quot;-&quot;,
  authDomain: &quot;give-authorization.firebaseapp.com&quot;,
  projectId: &quot;give-authorization&quot;,
  storageBucket: &quot;give-authorization.appspot.com&quot;,
  messagingSenderId: &quot;-&quot;,
  appId: &quot;-&quot;
};

const foundationsConfig = {
  apiKey: &quot;-&quot;,
  authDomain: &quot;give-foundationsorganization.firebaseapp.com&quot;,
  projectId: &quot;give-foundationsorganization&quot;,
  storageBucket: &quot;give-foundationsorganization.appspot.com&quot;,
  messagingSenderId: &quot;-&quot;,
  databaseURL: &quot;&quot;,
  appId: &quot;-&quot;
};
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);

const foundationsApp = initializeApp(foundationsConfig, &quot;foundations&quot;);
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 &quot;firebase/app&quot;;

const firebaseConfig = {
  apiKey: &quot;-&quot;,
  authDomain: &quot;give-authorization.firebaseapp.com&quot;,
  projectId: &quot;give-authorization&quot;,
  storageBucket: &quot;give-authorization.appspot.com&quot;,
  messagingSenderId: &quot;-&quot;,
  appId: &quot;-&quot;
};

const foundationsConfig = {
  apiKey: &quot;-&quot;,
  authDomain: &quot;give-foundationsorganization.firebaseapp.com&quot;,
  projectId: &quot;give-foundationsorganization&quot;,
  storageBucket: &quot;give-foundationsorganization.appspot.com&quot;,
  messagingSenderId: &quot;-&quot;,
  databaseURL: &quot;&quot;,
  appId: &quot;-&quot;
};
initializeApp(firebaseConfig);

initializeApp(foundationsConfig, &quot;foundations&quot;);

And here how your component should look like.

import { useState, useEffect } from &quot;react&quot;;
import { getDoc, doc, getFirestore, getApp } from &quot;@firebase/firestore&quot;

const Fetch = () =&gt; {
  const [allDocs, setAllDocs] = useState([]);
  const [singleDoc, setSingleDoc] = useState({});

  const fetchAll = async (e) =&gt; {
    const result = await getDoc(doc(getFirestore(getApp(&#39;foundations&#39;)), &#39;f_collections&#39;))
    if(result.exists) {
        result.data.forEach(docSnap =&gt; {
            setAllDocs(prev =&gt; [...prev, docSnap.data()])
        })
    }
    console.log(allDocs);
  };

   return (
    &lt;div className=&quot;&quot;&gt;
      qwerty
      &lt;button type=&quot;button&quot; onClick={fetchAll} className=&quot;&quot;&gt;
        Fetch
      &lt;/button&gt;
    &lt;/div&gt;
  );
};

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.

huangapple
  • 本文由 发表于 2023年4月13日 16:23:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76003233.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定