How to map firebase documents using javascript? - javascript

I need to display transaction data in interface, but i dont understand how to map documents to see different data in each doc.
import React, { useContext, useEffect, useState } from "react";
import "firebase/compat/auth";
import "firebase/compat/firestore";
import { db } from "../../firebase";
import { doc, getDoc } from "firebase/firestore";
import { UserContext } from "../../context/UserContext";
const TransactionHistoryComponent = () => {
async function getUserTransaction() {
const docRef = doc(
db,
"transactions",
txhash,
"userTransactions",
"5TS44z5iPOzWaj3F4uRr"
);
const docSnap = await getDoc(docRef);
if (docSnap.exists()) {
console.log("Document data:", docSnap.data());
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
}
}
const { txhash } = useContext(UserContext);
useEffect(() => {
getUserTransaction();
i tried to enter a name of document and this works but only with one document. i need to see 1, 2, and 32744342390493 document data in interface by some sort of mapping this documents

Related

How to check whether I'm getting data from cache or firestore (JavaScript SDK)?

I enabled the firestore cache by calling the enableIndexedDbPersistence method in my react app. here is my code:
import { initializeApp } from "firebase/app"
import { getAuth } from "firebase/auth"
import { enableIndexedDbPersistence, getFirestore } from "firebase/firestore"
const firebaseConfig = {
// config code
}
initializeApp(firebaseConfig)
const db = getFirestore()
enableIndexedDbPersistence(db) // enable cache
const auth = getAuth()
export { auth, db }
I would like to know how I can verify that I'm getting data from the cache, not from the server in the below code?
import { useEffect, useState } from "react"
import { collection, limit, onSnapshot, orderBy, query, where } from "firebase/firestore"
import { db } from "../firebase/config"
export const useCollection = (c) => {
const [documents, setDocuments] = useState([])
const [isLoading, setIsLoading] = useState(true)
const [error, setError] = useState(null)
useEffect(() => {
let ref = collection(db, c)
const unsubscribe = onSnapshot(ref, (snapshot) => {
const results = []
console.log(snapshot.metadata.fromCache ? "local data" : "server data")
snapshot.docs.forEach(
(doc) => {
results.push({ ...doc.data(), id: doc.id })
},
(error) => {
console.log(error)
setError("could not fetch the data")
}
)
setDocuments(results)
setIsLoading(false)
setError(null)
})
return () => unsubscribe()
}, [])
return { documents, error, isLoading }
}
Is there anything apart from calling the enableIndexedDbPersistence method I need to do to configure the cache properly?
Will this method cache the subcollection documents as well?

Why I receive "TypeError: doc is not a function" (Firebase 9, Firestore)

I try to add a user in Firestore with a custom ID.
import { db } from "../firebase/config";
import {collection, addDoc, deleteDoc, updateDoc, doc, setDoc} from 'firebase/firestore'
export const useFirestore = (collections) => {
const addDocumentUser = async (doc, id) => {
try{
const addedDocument = await setDoc(doc(db, collections, id), {...doc});
return addedDocument.id
}
catch(err){
console.log(err)
dispatch({type: 'ERROR', payload: err})
}
}
return {addDocumentUser}
}
When I run it I receive following error in the consol:
TypeError: doc is not a function
at addDocumentUser (useFirestore.js:62:1)
at useSignup.js:29:1
at async signup (useSignup.js:23:1)
at async handleSubmit (Signup.js:23:1)
What I am doing wrong?
I imported everything and the database access works for functions (addDoc) without the custom id.
The problem is that you're redefining doc, so it has two definitions:
import { db } from "../firebase/config";
import {collection, addDoc, deleteDoc, updateDoc, doc, setDoc} from 'firebase/firestore'
// 👆
export const useFirestore = (collections) => {
const addDocumentUser = async (doc, id) => {
// 👆
try{
const addedDocument = await setDoc(doc(db, collections, id), {...doc});
...
That second doc that I point out hides the function that you import before.
The solution is to use a different name:
import { db } from "../firebase/config";
import {collection, addDoc, deleteDoc, updateDoc, doc, setDoc} from 'firebase/firestore'
export const useFirestore = (collections) => {
const addDocumentUser = async (data, id) => {
// 👆
try{
const addedDocument = await setDoc(doc(db, collections, id), {...data});
// 👆
...

Can't use firebase in React component, because it's not initialized [duplicate]

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)

Read Collection in firebase from vue js

I am trying to read a collection with specific name from firebase firestore, but I get an error which I couldn't find answer for it.
Here you can see my boot file:
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
import { getAuth, createUserWithEmailAndPassword } from "firebase/auth";
import { collection, query, where, doc, getDoc } from "firebase/firestore";
const firebaseApp = initializeApp({
apiKey: "####",
authDomain: "####",
projectId: "####",
});
const db = getFirestore();
const auth = getAuth();
const createUser = createUserWithEmailAndPassword();
export default {db, auth, createUser};
Here is my script tag in .vue file:
<script>
import { collection, getDocs } from "firebase/firestore";
import db from "src/boot/firebase"
export default {
setup() {
return {
waitingList: {},
};
},
created() {
const querySnapshot = await getDocs(collection(db, "waitingList"));
querySnapshot.forEach((doc) => {
// doc.data() is never undefined for query doc snapshots
console.log(doc.name, " => ", doc.data());
});
},
};
</script>
and here you can see the list of errors I got:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'tenantId')
FirebaseError: Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore
The imported db would be an object containing instances of Firestore and Auth. Try changing your import as shown below:
import { db } from "src/boot/firebase"
// instead of import db from "..."
export default {
setup() {
return {
waitingList: {},
};
},
async created() {
const querySnapshot = await getDocs(collection(db, "waitingList"));
querySnapshot.forEach((doc) => {
console.log(doc.name, " => ", doc.data());
});
},
};
Also change export default { db } to export { db } in the boot file.

Why firebase onAuthStateChanged always return a null value?

import firebase from "firebase/app";
import "firebase/auth";
import firebaseConfig from '../../FirebaseConfig';
import { useEffect, useState } from 'react';
if(!firebase.apps.length){
firebase.initializeApp(firebaseConfig);
}
const AuthChange = () => {
const [UserInfo, setUserInfo] = useState();
useEffect(() => {
firebase.auth().onAuthStateChanged(function(user) {
console.log('AuthChanged', user)
if (user) {
const information = {name: user.displayName}
setUserInfo(information);
} else {
setUserInfo(null);
}
});
}, [])
return UserInfo;
}
export default AuthChange;
The output is
Authentication.js:14 AuthChanged null
.
The output is always null, whether the user is signed in or not. How can I solve It?

Categories