How to set useState by checking User data in Firebase - javascript

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()

Related

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)

getApp is not defined

I'm using firebase for a SvelteKit project. I'm getting the following error only after reloading:
getApp is not defined
from the file /src/routes/admin/index.svelte:
import { initializeApp, getApps, getApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
const firebaseConfig = {
// (config info)
};
const firebaseApp =
(getApps().length === 0 ? initializeApp(firebaseConfig) : getApp());
const db = getFirestore();
const colRef = collection(db, "questions");
Why does firebase work until I reload? I'm guessing it's something to do with the fact that only the first page load is server rendered? Does getApp() not work on the client?

Firebase Reactjs - ae.collection is not a function

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';

VueJS Firebase app problem of export default error

I'm trying to create crud app with vue 2 and firebase latest, &
this is my firebase.js file
import firebase from 'firebase/app'
import 'firebase/auth'
import 'firebase/firestore'
const firebaseConfig = {
stuff
};
firebase.initializeApp(firebaseConfig);
const database = firebase.firestore()
const auth = firebase.auth()
const usersCollection = database.collection('users')
export{
database,
auth,
usersCollection
}
and here is my store/index.js file
import Vue from "vue";
import Vuex from "vuex";
import fb from "../../firebase"
import router from "../router";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
userProfile:{}
},
mutations: {
setUserProfile(state,val)
{
state.userProfile=val
},
setPerformingRequest(state,val)
{
state.performingRequest=val
}
},
actions: {
async login({dispatch},form)
{
const{user} = await fb.auth().signInWithEmailAndPassword(form.email,form.password)
dispatch('fetchUserProfile',user)
},
async signUp({dispatch},form)
{
const {user} = await fb.auth().createUserWithEmailAndPassword(form.email,form.password)
// create user object in userCollection
await fb.usersCollection.doc(user.uid).set({
firstName:form.firstName,
middleName:form.middleName,
lastName:form.lastName,
email:form.email,
password:form.password,
gender:form.gender,
age:form.user_age
})
dispatch('fetchUserProfile',user)
},
async fetchUserProfile({commit},user)
{
// fetching user profile data into constant named userProfile
const userProfile = await fb.usersCollection.doc(user.uid).get()
// setting the fetched data from firebase to state of userProfile
commit('setUserProfile',userProfile.data())
// now changing route to dashboard
if(router.currentRoute.path ==='/')
{
router.push('/Dashboard')
}
},
async logOut({commit})
{
// log user out
await fb.auth.signOut()
// clear user data from state
commit('setUserProfile',{})
// changing route to homepage
router.push('/')
}
},
modules: {},
});
the application runs with warning in browser console Uncaught (in promise) TypeError: firebase__WEBPACK_IMPORTED_MODULE_4_.default is undefined and in vs code terminal
"export 'default' (imported as 'fb') was not found in '../../firebase'
and because of that neither user is getting registered nor the document is getting created
Does anyone know how to do this ?
Changing to
const fb = require('../../firebase.js');
or to
import { auth, usersCollection } from "../../firebase";
in the store file should do the trick.
In the first case, you need to also change
await fb.auth().createUserWithEmailAndPassword
to
await fb.auth.createUserWithEmailAndPassword
In the second case, change
await fb.auth().createUserWithEmailAndPassword
to
await auth.createUserWithEmailAndPassword
In this case, also note that if you would use database in the store/index.js file you would need to import database as well, like:
import { database, auth, usersCollection } from "../../firebase";
More explanations here and here.

The behavior for Date objects stored in Firestore is going to change and your app may break

I am stuck at this point while working on VueJs as i want to log the data from firebase .
I changed the code according to the suggestions on the console but nothing is working . I am using Vue Cli 3 and firebase 5.5.9 .
<script>
import db from './firebaseInit'
export default {
name: 'dashboard',
data(){
return{
employees: []
}
},
created(){
db.collection('employees').get().then
(querySnapshot => {
querySnapshot.forEach(doc => {
console.log(doc.data())
const data = {
}
})
})
}
}
</script>
This is my firebaseInit.js
import firebase from 'firebase'
import 'firebase/firestore'
import firebaseConfig from './firebaseConfig'
const firebaseApp = firebase.initializeApp(firebaseConfig)
// const firestore = firebase.firestore();
// const settings = {timestampsInSnapshots: true};
// firestore.settings(settings);
export default firebaseApp.firestore()
As shown in both the error message and this github issue, you need to initialize the firestore object with an instruction on how to store date/timestamp fields.
So:
import firebase from 'firebase'
import 'firebase/firestore'
import firebaseConfig from './firebaseConfig'
const firebaseApp = firebase.initializeApp(firebaseConfig)
const firestore = firebase.firestore();
const settings = {timestampsInSnapshots: true};
const api = firestore.settings(settings);
export default api;
import firebase from "firebase";
import "firebase/firestore";
import firebaseConfig from "./firabaseConfig.js";
const firebaseApp = firebase.initializeApp(firebaseConfig);
firebaseApp.firestore().settings({ timestampsInSnapshots: true });
export default firebaseApp.firestore();
it works for me. you can give it a try. :)

Categories