I don't understand why I can't get data from firebase firestore database.
my error :
[FirebaseError: Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore]
My config file with firebase config is correctly set, I can add Data with this model :
{ item: { ...event, date } }
My files structures : picture of my structure
I have correctly declared my state, I have async await with try catch.
I have used this from firebase documentation
EventList.js
import { FlatList, View, Text, StyleSheet } from "react-native";
import React, { useState, useEffect } from "react";
import { EVENTS_COLLECTION } from "../commons/constants";
import db from "../commons/services/firebase";
const EventList = () => {
const [events, setEvents] = useState([]);
return (
<View>
<FlatList
data={events}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<View style={styles.eventContainer}>
<Text style={styles.eventName}>{item.name}</Text>
<Text style={styles.eventDate}>{item.date.toString()}</Text>
</View>
)}
/>
</View>
);
};
firebase.Js
const firebaseConfig = {
apiKey: "",
authDomain: "",
databaseURL:
"",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: "",
measurementId: "",
};
const app = initializeApp(firebaseConfig);
export const db = getFirestore(app);
I try to get all documents from my events collection.
My goal is to make an Calendar with event manager with firebase firestore database
In firebase.js you export db like this:
export const db = getFirestore(app);
This is a named export, therefore you will need a named import:
import { db } from '../commons/services/firebase'
// or
// import * as config from '../commons/services/firebase'
// const db = config.db
The way you import is for default exports and results in your case with undefined. Therefore firebase complains that the first argument to collection is not correct (it's undefined).
You can read more about imports here.
Try this one if EVENTS_COLLECTION returns the name of the collection correctly then you will get all documents otherwise use "Collection Name" where you write EVENTS_COLLECTION.
const fetchEvents= async () => {
await db.collection(EVENTS_COLLECTION).onSnapshot({
error: e => console.error(e),
next: (querySnapshot) => {
var data = [];
var i = 0;
querySnapshot.forEach(doc => {
data.push(doc.data());
console.log(doc.id, " => ", doc.data());
});
setEvents(data)
},
})
};
Related
I'm working on connecting a Firestore database collection to a Next.js app. The app is very simple, as I am just fetching data and displaying it on the screen. I have a collection with two items in Firestore right now, and I'm trying to get it to console.log() to verify that it is connecting. However, when I do, the console shows me two Arrays, but they don't seem to hold any of the data from my database.
I am currently using this code to log the data to the console:
import React, { useEffect, useState } from 'react'
import {collection, getDocs} from 'firebase/firestore';
import db from '../firebase/config'
import { Box } from '#chakra-ui/react'
import ProductCard from './ProductCard'
const Products = () => {
const [products, setProducts] = useState([])
useEffect(() => {
;(async () => {
const colRef = collection(db, 'products')
const snapshots = await getDocs(colRef)
const docs = snapshots.docs.map((doc) => {
const data = doc.data()
data.id = doc.id
return data
})
setProducts(docs)
console.log(docs)
})()
}, [])
I can provide the rest of the code, if necessary.
My firebase config file looks like this:
import { initializeApp } from "firebase/app";
import { getFirestore } from 'firebase/firestore';
const firebaseConfig = {
apiKey: "---",
authDomain: "---",
projectId: "---",
storageBucket: "---",
messagingSenderId: "---",
appId: "---",
measurementId: "---",
};
const app = initializeApp(firebaseConfig);
const db = getFirestore(app)
export default db
The Arrays I get look like this:
The database currently looks like this:
Does anybody have an idea, or can point me in the right direction?
Thanks in advance!
From your database screenshot we can deduce that products is not a root collection but a subcollection of a document (which actually does not exist). (See last note at the bottom)
So you need to declare the CollectionReference with the entire path of the (sub)collection. We don't know the name of the root collection and we just see a part of the ID of the parent document (cocoworksco...) but you should declare the subcollection CollectionReference as follows:
let colRef = collection(db, 'rootCollection/cocoworksco.../products');
let querySnapshot = await getDocs(colRef);
// ...
Note that they are many different possibilities to declare the subcollection: For example, collection(db, 'rootCollection', 'cocoworksco...', 'products') or collection(db, 'rootCollection', 'cocoworksco.../products'); are also valid.
Note also that we are actually not sure that the path of the subcollection is composed of three parts since we don't see the full path on the screenshot. It is possible that it is deeper, e.g. rootCollection/doc1/subCol1/cocoworksco.../products.
I have been trying to fetch posts from Firestore for users with a given ID in Reactjs but no success.
I keep getting this error from console;
App.js:64 Uncaught (in promise) TypeError: (0 , firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.getDocs)(...).where is not a function
at getPost (App.js:64:1)
at App.js:69:1
at invokePassiveEffectCreate (react-dom.development.js:23487:1)
at HTMLUnknownElement.callCallback (react-dom.development.js:3945:1)
at Object.invokeGuardedCallbackDev (react-dom.development.js:3994:1)
at invokeGuardedCallback (react-dom.development.js:4056:1)
at flushPassiveEffectsImpl (react-dom.development.js:23574:1)
at unstable_runWithPriority (scheduler.development.js:468:1)
at runWithPriority$1 (react-dom.development.js:11276:1)
at flushPassiveEffects (react-dom.development.js:23447:1)
Here is my code;
import React, { useEffect, useState } from 'react'
import { collection, getDocs } from "firebase/firestore";
import { db } from '../firebase-config'
const [posts, setPosts] = useState([])
const postRef = collection(db, "posts")
useEffect(() => {
const getPost = async () => {
const data = await getDocs(postRef)
.where('userId', '==', '12345').orderBy("createdAt").get()
setPosts(data.docs.map((doc) => ({ ...doc.data(), id: doc.id })));
};
getPost();
}, []);
My firebase-config.js looks like this;
import { initializeApp } from "firebase/app";
import { getFirestore } from "#firebase/firestore"
const firebaseConfig = {
apiKey: "xzy",
authDomain: "xzy",
databaseURL: "xzy",
projectId: "xzy",
storageBucket: "xzy",
messagingSenderId: "xzy",
appId: "xzy",
};
const app = initializeApp(firebaseConfig)
export const db = getFirestore(app)
If I remove this statement, .where('userId', '==', '12345').orderBy("createdAt").get()
It fetches all the posts from the database which is not what I want. I want to be able to fetch only posts that matches a specific ID.
Any help will be highly appreciated.
You are using the new Firebase Modular SDK that uses a functional syntax instead of the older namespaced one. You now need to use the top-level function query() to build a Query and other QueryConstraints like where, orderBy, limit are also functions. Try refactoring the code as shown below:
import { collection, getDocs, query, where } from "firebase/firestore"
useEffect(() => {
const getPost = async () => {
const q = query(postRef, where("userId", "==", "12345"));
const data = await getDocs(q)
setPosts(data.docs.map((doc) => ({
...doc.data(),
id: doc.id
})));
};
getPost();
}, []);
Also checkout: Firestore: What's the pattern for adding new data in Web v9? and the documentation that includes examples with both the syntaxes.
As the title says, I'm trying to build out a blog site and I have most of it done expect for clicking on a post stub to read the full post. I keep getting this error anytime I go to the post page.
Error: Error serializing .post returned from getServerSideProps in "/posts/[slug]".
Reason: undefined cannot be serialized as JSON. Please use null or omit this value.
I've searched everywhere to try and figure out what I'm doing wrong but can't seem to find the right answer.
Here is by firebase code.
import {
collection,
getDocs,
getFirestore,
limit,
onSnapshot,
orderBy,
query,
doc,
setDoc,
getDoc,
} from "firebase/firestore";
import firebase from "firebase/app";
import { initializeApp, getApps, getApp } from "firebase/app";
import { getAuth, GoogleAuthProvider } from "firebase/auth";
import { Timestamp, toJSON } from "firebase/firestore";
// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
apiKey: "AIzaSyAB4SbXl-I1TMoa31ybnCzmTASXjZFnMAg",
authDomain: "personal-blog-8decb.firebaseapp.com",
projectId: "personal-blog-8decb",
storageBucket: "personal-blog-8decb.appspot.com",
messagingSenderId: "473768411808",
appId: "1:473768411808:web:c464d23c531b8bdaa4bfc5",
measurementId: "G-6F04591W4N",
};
if (!getApps().length) {
initializeApp(firebaseConfig);
}
const db = getFirestore();
//Reads all the posts in the database
export const getPosts = async () => {
const q = query(collection(db, "posts"), orderBy("date", "desc"));
const querySnapShot = await getDocs(q);
const posts = querySnapShot.docs.map((doc) => ({
...doc.data(),
id: doc.id,
date: doc.data().date?.toDate().getTime(),
}));
return posts;
};
// Get one post from database based on the slug.
export const getPostBySlug = async (slug) => {
const docRef = doc(db, "posts", `${slug}`);
const docSnap = await getDoc(docRef);
if (docSnap.exists()) {
return docSnap.data();
} else {
console.log("No Such Document");
}
};
// Adds posts to the database
export const createPost = async (post) => {
await setDoc(doc(db, "posts", `${post.slug}`), {
title: post.title,
content: post.content,
date: Timestamp.fromDate(new Date()),
});
};
export const auth = getAuth();
export const googleAuthProvider = new GoogleAuthProvider();
And here is the slug page.
import { async } from "#firebase/util";
import { useRouter } from "next/router";
import { getPostBySlug } from "../../lib/firebase";
import moment from "moment";
export async function getServerSideProps() {
const post = await getPostBySlug();
return {
props: {
post,
},
};
}
export default function PostPage({ post }) {
<div className="post">
<h1>{post.title}</h1>
<span>Published {moment(post.date).format("LL")}</span>
<p dangerouslySetInnerHTML={{ __html: post.content }}></p>
</div>;
}
Thanks in advance.
So here is how I got it to work. First I changed the firebase read file to a custom query.
// Get one post from database based on the slug.
export const getPostBySlug = async (slug) => {
const q = query(collection(db, "posts"), where("slug", "==", `${slug}`));
const querySnapShot = await getDocs(q);
const post = querySnapShot.docs.map((doc) => ({
...doc.data(),
id: doc.id,
date: doc.data().date?.toDate().getTime(),
}));
return post;
I had to do it this way because of the timestamp I used with firestore. I couldn't figure out any other way to serialize it to json.
Next I changed the getServerSideProps function in the slug js file to take a context query.
export async function getServerSideProps(context) {
const post = await getPostBySlug(context.query.slug);
console.log("this is the severside props: ", post);
return {
props: {
post,
},
};
}
After that it worked fine. There are probably better approached to this but this is what worked for me.
I am new in react. Last day i tried to do work with Firebase in a react JS project. But i stuck on that. I set up sign in method according to the Firebase and i wanted to display all display name,email,photoUrl from the user who are sign in through sign in button.But i faced a problem i couldn't show these data but my console said i passed data successfully. I saw all data by console but why i don't show on the page. I try to fix all error but it's not change anything.My code is below:
import './App.css';
import firebase from "firebase/app";
import "firebase/auth";
import "firebase/firestore";
import firebaseConfig from './firebase.confige';
import React,{useState} from 'react';
// firebase.initializeApp(firebaseConfig)
if(!firebase.apps.length){
firebase.initializeApp(firebaseConfig);
}
function App() {
const [user,setUser] = useState(
{
isSignIn: false,
name: '',
email: '',
photo: ''
})
console.log(user)
const provider = new firebase.auth.GoogleAuthProvider();
const handleSignIn = ()=>{
firebase.auth().signInWithPopup(provider)
.then(res => {
const {displayName, photoURL, email} = res.user;
const signedInUser = {
isSignIn:true,
name: displayName,
email: email,
photo:photoURL
}
setUser(signedInUser);
// console.log(displayName,email,photoURL);
})
.catch(err => {
console.log(err);
console.log(err.message);
})
}
return (
<div className="App">
<button onClick={handleSignIn}>Sign In</button>
{
user.isSignedIn &&
<div>
<p> Welcome, {user.name}</p>
<p>Your email: {user.email}</p>
<img src={user.photo} alt=""/>
</div>
}
</div>
);
}
export default App;
firebase.Confige.js file is here:
const firebaseConfig = {
apiKey: "AIzaSyBPt45m9rGYcMJy5Ynq4PtEroNsSDYUcUM",
authDomain: "ema-john-simple-61839.firebaseapp.com",
projectId: "ema-john-simple-61839",
storageBucket: "ema-john-simple-61839.appspot.com",
messagingSenderId: "813068797804",
appId: "1:813068797804:web:297c9d66d20a005cd15549",
measurementId: "G-8DGK2DEVBS"
};
export default firebaseConfig;
first starting with sign in
console show user name email and photo
display show nothing
I didn't find out any solution please help me why this is happening i have to find out
You're checking for value user.isSignedIn in your JSX and, if truthy, are displaying your values.
However, earlier in your handleSignIn method, you adjust the property isSignIn value to true if the sign-in is successful.
You should be checking for isSignIn in your JSX instead of isSignedIn.
Trying to set up some testdata in React Native using Firebase. I have successfully installed using $yarn add firebase. I have added test data in FB like this:
FB data
And in my project I added the following code:
import * as firebase from 'firebase'
const firebaseConfig = {
apiKey: "AIzaSyBNKM6Ptbynkg5dEJkwMHNsZhUCsW2JqGE",
authDomain: "testproject-f4c9f.firebaseapp.com",
databaseURL: "https://testproject-f4c9f.firebaseio.com",
projectId: "testproject-f4c9f",
storageBucket: "testproject-f4c9f.appspot.com",
messagingSenderId: "48530616964"
}
firebase.initializeApp(firebaseConfig)
Then in the rendering:
let mytext = ""
let testing =
firebase.database().ref('testCategory/test1/FirstHeader');
testing.on('value', function(snapshot) {
mytext = snapshot.val()
});
return(
<View>
<Text>{mytext}</Text>
</View>
);
Running the app, nothing shows. Any ideas would be appreciated.
UPDATE:
I managed to get it right in the console.log with this code:
let child = ""
var ref = firebase.database().ref("testCategory");
ref.once("value")
.then(function(snapshot) {
child = snapshot.child("test1/testHeader").val()
console.log({child})
});
But for some reason I can't print it in the text output:
return(
<View>
<Text>{this.child}</Text>
</View>
);
It's just blank...
You need to pass the data from the callback to the view. You should use a state manager like Redux or MobX, but for this example, you can just use the component state.
This is what your component should look like.
class Hello extends Component {
state = {
child: ''
}
componentDidMount() {
firebase
.database()
.ref('testCategory')
.on('value')
.then(snapshot => {
const child = snapshot.child('test1/testHeader').val()
this.setState({
child
})
})
}
render() {
const { child } = this.state
return (
<View>
<Text>{child}</Text>
</View>
)
}
}
Tada!