I can't figure out what is the error here. I made the tutorial Firebase/website and did the same things in my project. I am trying to print out the collection I created on Firebase in my React website but got the error at the line db.collection : Uncaught (in promise) TypeError: ae.collection is not a function
component.js :
// React
import { useState, useEffect } from "react";
import { db, collection, getDocs } from '../../../firebase.js';
const [holder, setHolder] = useState([]); // update
db.collection("holder").onSnapshot((snapshot) => {
setHolder(
snapshot.docs.map((doc) => ({
id: doc.id,
data: doc.data(),
}))
);
});
console.log({ holder });
update : firebase.js below
// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import { getAnalytics } from "firebase/analytics";
import { getFirestore, collection, getDocs } from 'firebase/firestore/lite';
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries
// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
...
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const analytics = getAnalytics(app);
export const db = getFirestore(app);
Thank you !
You are using Firebase Modular SDK which has a completely new syntax and you must use the same in your code. Try refactoring the code to this:
// React
import { useState, useEffect } from "react";
import { db } from '../../../firebase.js';
import { onSnapshot, collection } from 'firebase/firestore'
const [holder, setHolder] = useState([]); // update
onSnapshot(collection(db, 'holder'), (snapshot) => {
setHolder(
snapshot.docs.map((doc) => ({
id: doc.id,
data: doc.data(),
}))
);
})
Also make sure your getFirestore import is from firebase/firestore and not from lite in firebase.js or you'll run into this issue:
import { getFirestore } from 'firebase/firestore';
Related
I can't seem to figure out how to set useState after querying Firebase.
I need BOX to be equal to "public URL" for everyone except for admin.
import { auth } from "../firebase";
...
const [BOX, setBox] = useState('');
useEffect(() => {
if (auth.currentUser?.email === "admin#yahoo.com") {
setBox("https://admin/link");
} else {
setBox("https://public/link");
}
},[auth]);
Errors are always different. Sometimes it returns "...empty link", sometimes "network request failed". Sometimes it does show the correct data, but it runs into one of the errors when I refresh the screen.
Here is my firebase file
// Import the functions you need from the SDKs you need
import * as firebase from "firebase";
import 'firebase/firestore';
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries
// Your web app's Firebase configuration
const firebaseConfig = {
...
};
// Initialize Firebase
let app;
if (firebase.apps.length === 0) {
app = firebase.initializeApp(firebaseConfig);
} else {
app = firebase.app()
}
const auth = firebase.auth();
const dbFirebase = app.firestore();
export {auth, dbFirebase};
You can not use hook inside an if statement...
const [box, setBox] = useState('');
useEffect(() => {
if (auth.currentUser?.email === "admin#yahoo.com") {
setBox("https://admin/link");
} else {
setBox("https://public/link");
}
},[auth]);
For firebase 9 you will need to configure it like below:
import { initializeApp } from 'firebase/app'
import { getAuth } from 'firebase/auth'
const firebaseConfig = {...}
initializeApp(firebaseConfig)
export const auth = getAuth()
I am making a food delivery app using react-native and redux. I want to fetch the data from the firebase store and for that, I have written a function in the actions.js, but whenever I run the app it shows the Error
Firebase: No Firebase App '[DEFAULT]' has been created - call Firebase App.initializeApp() (app/no-app).
Here is the function which I am using to fetch the data
action.js
import firebase from "firebase"
export const ProductDetails = (data) => {
return {
type: "PRODUCT_ITEMS",
payload: {
data,
},
};
};
var db = firebase.firestore();
var docRef = db.collection("Products").doc("Items");
export const FetchItems = () => {
return async function (dispatch) {
return await docRef
.get()
.then((doc) => {
if (doc.exists) {
console.log("Document Data", doc.data());
dispatch(ProductDetails(doc.data));
} else {
console.log("NO such document");
}
})
.catch((error) => {
console.log(error);
});
};
};
Here is my App.js file
import React, { useState } from "react";
import { StyleSheet, Text, View, Dimensions } from "react-native";
import { NavigationContainer } from "#react-navigation/native";
import AppStack from "./components/navigation/AppStack";
import firebase from "firebase";
import {Provider} from "redux"
import store from "./store"
import { useDispatch, useSelector, Provider } from "react-redux";
import store from "./redux/store";
import AppWrapper from "./AppWrapper";
export default function App() {
const firebaseConfig = {
};
if (firebase.apps.length === 0) {
firebase.initializeApp(firebaseConfig);
}
return (
<Provider store={store}>
<NavigationContainer>
<AppStack />
</NavigationContainer>
</Provider>
);;
}
I would recommend creating a separate file firebase.js and export Firebase services from there after initialization.
firebase.js
import firebase from 'firebase/app';
import 'firebase/firestore'
const firebaseConfig = {...};
if (!firebase.apps.length) {
firebase.initializeApp(config);
}
export const auth = firebase.auth();
export const firestore = firebase.firestore()
Then import these wherever you need them:
// App.js for example
import {firestore, auth} from './firebase.js'
//var docRef = firestore.collection("Products").doc("Items");
for users with expo(v44) and firebase(v9)
firebaseUtil.js
import { initializeApp, getApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
import { getAuth } from "firebase/auth";
// Initialize Firebase
const firebaseConfig = {
...
};
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);
const auth = getAuth(app);
export { db, auth };
Login.js
import { auth } from "../../util/firebaseUtil";
export default function Login() {
const onSignUp = () => {
signInWithEmailAndPassword(auth, email, password);
};
return (
...
)
}
I think my error is caused by Webpack chunking(bootstrap). I did import the file with initializeApp(). My work around for who has the same problem.
Modularize the initializeApp in one file(initFire for me) and export anything(doesn't have to be app)
Import & Export before first usage of getApp()(methods like getAuth() will call it),
In this way, after Webpack it will still run first. (ES6 export {app} from "./initFire")
(This answer is grepped from my own GitHub Wiki, not plagiarizing)
i installed firebase in react app and initialized like this
// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import { getAuth, GoogleAuthProvider } from "firebase/auth"
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries
// Your web app's Firebase configuration
const firebaseConfig = {....};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
// export
export const auth = getAuth(app);
export const googleAuthProvider = new GoogleAuthProvider();
and imported this file into my react component like this
import {auth} from '../../firebase';
and i try to use it like this
await auth.sendSignInLinkToEmail(email, config);
and it give me this error
In Firebase v9+, you need to use the modular sendSignInLinkToEmail():
import { auth } from '../../firebase';
import { sendSignInLinkToEmail } from "firebase/auth"
await sendSignInLinkToEmail(auth, email, config);
You can catch these errors yourself by familiarizing yourself with the namespaced SDK to modular SDK upgrade process.
So I have a simple React Native app that I created using Expo and debug on my personal Android device.
I've included firebase/firestore into my app and am now trying to add an object to firestore on button click.
Here's my code:
firebaseConfig.js :
import { initializeApp } from '#firebase/app';
var config = {
...
}
const app = initializeApp(config);
export default app;
Component:
import { app } from '../firebaseConfig';
import { getFirestore } from 'firebase/firestore/lite';
import { doc, setDoc, collection, query, where, getDocs, initializeFirestore } from "firebase/firestore";
...
export default function Component() {
const firestoreDb = getFirestore(app);
// this function is called when clicking a button
const onAddListPress = () => {
setDoc(doc(firestoreDb, "cities", "LA"), {
name: "Los Angeles",
state: "CA",
country: "USA"
});
}
}
This throws the following error:
Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore
This code above (in the onPress) is copied from the official firestore docs, here:
https://firebase.google.com/docs/firestore/manage-data/add-data#set_a_document
Does anyone have an idea why this does not work?
I suggest you edit your post and remove the firebaseConfig configuration keys, or delete your Firebase app and create a new one from the Firebase console to secure your app. I tried to replicate your application using React, and I received the same error message. There were two changes I made to correct the error. The first one is inside the firebaseConfig file, the default export needs to be changed to a named export:
import { initializeApp } from "firebase/app"
const firebaseConfig = {
//Project configuration keys
};
const app = initializeApp(firebaseConfig);
export { app }; // Change from a default to a named export
In addition, all the imports inside your component should come from the full Javascript SDK, not the lite version. The lite version has some limitations which can result in this specific error.
import { app } from "./firestore-config";
import { getFirestore, getDoc, doc } from "firebase/firestore";
import './App.css';
export default function App() {
const firestoreDB = getFirestore(app);
const docRef = doc(firestoreDB, "users", "testUser1");
const getData = async () => {
const data = await getDoc(docRef);
console.log(data);
}
getData();
return <div className="App"></div>;
}
You might also want to review this GitHub issue if you are using yarn to manage your dependencies.
Other important information:
Project uses React Library
Initialized with Create React App
This is how my code typically looks like on v8:
// firebase.js
import firebase from "firebase/app";
import "firebase/firestore";
export const app = firebase.initializeApp(config);
export const firestore = app.firestore();
// app.js
import { firestore } from './firebase'
firestore.collection("users").get().then((querySnapshot) => {
querySnapshot.forEach((doc) => {
console.log(`${doc.id} => ${doc.data()}`);
});
});
I believe with v9, Firebase no longer has that side effect import problem, and so now we explicitly state what functions we want from a package.
// firebase.js
import { initializeApp } from 'firebase/app'
import { getFirestore } from 'firebase/firestore'
export const app = initializeApp(config)
export const firestore = getFirestore()
Code below is from Firebase docs
// app.js
import { addDoc, collection } from "firebase/firestore";
try {
const docRef = await addDoc(collection(db, "users"), {
first: "Alan",
middle: "Mathison",
last: "Turing",
born: 1912
});
console.log("Document written with ID: ", docRef.id);
} catch (e) {
console.error("Error adding document: ", e);
}
Will the code above (which uses the addDoc and collection imports) refer to the initialized Firestore instance in firebase.js, or is there a proper way to use the initialized Firestore instance?
Firestore instances are managed from the core Firebase App, the firestore modules only include the libraries to make the requests. The solution to getting the Firestore instance without having to reference the core app is to request the instance from the Firestore modules.
import { getFirestore } from 'firebase/firestore';
const db = getFirestore();
Source: https://firebase.google.com/docs/firestore/quickstart#initialize