I'm trying to modularize my code as best as I can. If sharing my App.js on github or something, I don't want to have to keep deleting the id's, I'd rather just include it on a separate file and just .gitignore it.
For some reason, my app is just really not liking the way I'm doing it and I'm having a tough time working around it. Any idea what I'm doing wrong?
This is my App.js file:
import firebase from 'firebase';
import {
apiKey,
authDomain,
databaseURL,
storageBucket,
messagingSenderId
} from './constants/Keys';
class App extends Component {
constructor(props) {
super(props);
this._navContext = initNavigationContext();
}
componentWillMount() {
const config = {
apiKey,
authDomain,
databaseURL,
storageBucket,
messagingSenderId
};
firebase.initializeApp(config);
}
render() {
return (
<Provider store={Store}>
<NavigationProvider context={this._navContext}>
<StackNavigation navigatorUID="root" id="root" initialRoute={Router.getRoute('auth')} />
</NavigationProvider>
</Provider>
);
}
}
export default App;
I've omitted the other import statements for here.
Here is my Keys file:
const apiKey = '//////';
const authDomain = '//////';
const databaseURL = '//////';
const storageBucket = '//////';
const messagingSenderId = '//////';
const facebookAppID = '//////';
export default {
apiKey,
authDomain,
databaseURL,
storageBucket,
messagingSenderId,
facebookAppID
};
Any idea what I'm doing wrong here?
I think your problem is that you are trying to destructure the default export, and what ES6 modules do is use destructuring for named exports. If your imported values have all undefined, it is likely the case. You can do the following:
export const apiKey = '//////';
export const authDomain = '//////';
export const databaseURL = '//////';
export const storageBucket = '//////';
export const messagingSenderId = '//////';
export const facebookAppID = '//////';
And then it should work.
Related
I have and Expo project with this firebase config file:
import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
import 'firebase/compat/firestore';
const firebaseConfig = {
...
};
if (!firebase.apps.length){
firebase.initializeApp(firebaseConfig);
}
export { firebase };
I'm calling its methods like this:
const [events, setEvents] = useState([]);
const evsRef = firebase.firestore().collection('testing');
const getEvents = () => {
evsRef.onSnapshot(
snapshot => {
const evs = [];
snapshot.forEach((doc)=>{
const {name, height, features:{good, better, best}} = doc.data();
evs.push({
key: doc.id,
name, height,
features:
{
good,
better,
best
}
})
})
setEvents(evs);
}
)
return;
}
useEffect(() => {
getEvents();
console.log('Testing: ', events);
},[events])
And I get this error:
TypeError: undefined is not an object (evaluating '_firebase.default.firestore')
Any ideas? I'm new to React-Native/Expo and I can't find any consisting examples as to what method to use for communication with firebase/firestore, so far I've been using collection(db, 'collection name') but this one seems more documented.
Turns out I was mixing up V9 with code from V8 as it was pointe out in the comments, the confusion started with me using the node.js examples as opposed to Web 9 examples, so be aware of that. Here's the code:
Firebase Config
import { initializeApp, getApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
import { getAuth, createUserWithEmailAndPassword, signInWithEmailAndPassword } from "firebase/auth";
import geofire from 'geofire';
const firebaseConfig = {...};
const app = initializeApp(firebaseConfig);
const firestore = getFirestore(app);
export default firestore;
And this is the query code:
const getEvents = async (dbx) => {
const eventsCol = collection(dbx, 'testing');
const eventSnapshot = await getDocs(eventsCol);
const eventList = eventSnapshot.docs.map((doc) =>
({
...doc.data(),
key: doc.id
})
);
setEvents(eventList)
return eventList;
}
I am trying to connect redux-state-sync for syncronize state in different tabs to my next-redux project. But I have a server error (TypeError: dispatch is not a function) in this line: initStateWithPrevTab(makeStore). So how can I fix this bug? I try to add initStateWithPrevTab(makeStore) as a const or inside arrow func, but it still doesn't work. It's my store.js file where I configure store:
const config = {};
const middlewares = [createStateSyncMiddleware(config)];
const rootReducer = combineReducers({
booking: reducer,
});
const makeStore = () =>
createStore(
withReduxStateSync(rootReducer),
undefined,
applyMiddleware([config])
);
initStateWithPrevTab(makeStore);
export const wrapper = createWrapper(makeStore, { debug: true });
I want to upload an image to firebase storage, version 9. I have working code for the firestore, but I cant for the life of me understand the firebase docs regarding uploading, and how to make it work for Vue (which also requires the import of a REF function).
my question is: How do I import the ref function in Vue and also import and use the ref function from firebase firestore?
This is what I have. It feels wrong to wrap the Firebase ref with a .value, but I just put it in there to get past the vue error.
vue component code fragment: <-- this works
if (imageFile.value) {
await uploadImage(imageFile.value);
console.log("image:" + url.value);
}
useStorage.js <--this is where everything breaks down trying to convert from Firebase 8 to 9. Is it the vue Ref function?
import { ref } from "vue";
import { projectStorage } from "../firebase/config";
import { uploadBytesResumable, getDownloadURL } from
"#firebase/storage";
const useStorage = () => {
const error = ref(null);
const url = ref(null);
const filePath = ref(null);
//I need to use ref with firestore here
const uploadImage = async (file) => {
filePath.value = `images/${file.name}`;
const storageRef = ref(projectStorage,
filePath.value).value;
try {
const res = await storageRef.put(file);
url.value = res.ref.getDownloadURL();
} catch (err) {
console.log(err.message);
error.value = err.message;
}
};
return { url, filePath, error, uploadImage };
};
export default useStorage;
config.js
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
import { getStorage } from "firebase/storage";
import { getAuth } from "firebase/auth";
const firebaseConfig = {
[info]
};
// init firebase
const firebaseApp = initializeApp(firebaseConfig);
// init firestore service
const db = getFirestore(firebaseApp);
// init firestore authorization
const auth = getAuth(firebaseApp);
const projectStorage = getStorage(firebaseApp);
export { db, projectStorage, auth };
You can set an alias for either of the imports as shown below:
import { ref } from "vue";
import { projectStorage } from "../firebase/config";
import { ref as storageRef } from "#firebase/storage";
const fileRef = storageRef(projectStorage, filePath.value);
// use storageRef here ^^^ instead of ref from vue
Also checkout: How to import two classes by the same name in javascript/es6?
I'm trying to setup firebase Auth into my nextjs project (it looks like the firebase documentation is not up-to-date via the release of the getAuth method).
While using firebaseUi (to get the automatic styling of the different auth providers), I get this error :
Here is the code (i'm just trying to render the firebaseUi component for now) :
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
import { getAuth } from "firebase/auth";
const firebaseConfig = {
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
// Initialize Cloud Firestore
const db = getFirestore(app);
// Initialize Firebase Authentication
const auth = getAuth(app);
export { db, auth }
Then in a template page for signin :
import { NavBar } from '../components';
import { StyledFirebaseAuth } from 'react-firebaseui/StyledFirebaseAuth';
import { auth } from '../firebase/initFirebase';
import { GoogleAuthProvider } from 'firebase/auth';
const firebaseui = require('firebaseui')
// // Initialize the FirebaseUI Widget using Firebase.
var ui = new firebaseui.auth.GoogleAuthProvider(auth);
function Signup() {
const firebaseUiConfig = {
signInFlow: 'popup',
signInSuccessUrl: '/',
tosUrl: '/terms-of-service',
privacyPolicyUrl: '/privacy-policy',
signInOptions: [
GoogleAuthProvider.PROVIDER_ID
]
}
return (
<div>
<NavBar />
<StyledFirebaseAuth uiConfig={firebaseUiConfig} firebaseAuth={auth} />
</div>
)
}
export default Signup
Thanks a lot in advance for your help, I don't understand what's going on :(
// EDIT //
I understand it has to deal with SSR. So I did try to dynamically import firebaseUi with next/dynamic. I don't get the error any longer but the page is now blank (just the navbar component renders). Is it because I am passing props inappropriately ?
import dynamic from "next/dynamic";
import { NavBar } from '../components';
import { auth } from '../firebase/initFirebase';
import { GoogleAuthProvider } from 'firebase/auth';
const AuthComponent = dynamic(() =>
import('react-firebaseui/StyledFirebaseAuth').then((mod) => mod.StyledFirebaseAuth)
)
function Signup() {
const firebaseUiConfig = {
// signInFlow: 'popup',
signInSuccessUrl: '/',
tosUrl: '/legal',
privacyPolicyUrl: '/legal',
signInOptions: [
GoogleAuthProvider.PROVIDER_ID
]
}
return (
<div>
<NavBar />
<AuthComponent uiConfig={firebaseUiConfig} firebaseAuth={auth} />
</div>
)
}
export default Signup
The idea here to disable SSR on the page which used firebaseui.
This can be done in two steps.
Use firebase ui or any library which needs window keywork to work.
import React from 'react';
import Modal from '#leafygreen-ui/modal';
import * as firebaseui from 'firebaseui'
import 'firebaseui/dist/firebaseui.css'
export default function AuthUi({open, setOpen}) {
return (
<>
<Modal open={open} setOpen={setOpen}>
// Modal Content goes here.
// Signup widgets comes here
</Modal>
</>
);
}
while importing the library, do something like this.
//__app.js
// import AuthUi from '../components/authUi'; >> Replace this by code below
import dynamic from 'next/dynamic'
const AuthUi = dynamic(
() => import('../components/authUi'),
{ ssr: false }
);
Now you would be able to use firebaseui without window error.
I have a react/nextjs app and I have firebase.js as follow:
import firebase from 'firebase/app'
import 'firebase/auth'
import 'firebase/analytics'
import 'firebase/firestore'
const firebaseConfig = {
apiKey: '...'
}
try {
firebase.initializeApp(firebaseConfig)
firebase.analytics()
} catch (err) {
if (!/already exists/.test(err.message)) {
console.error('Firebase initialization error', err.stack)
}
}
export default firebase
I kept getting
Firebase initialization error ReferenceError: navigator is not defined
after adding analytics to the firebase.js file. What is the correct way to add analytics to the app?
import { getAnalytics, isSupported } from "firebase/analytics";
const analytics = isSupported().then(yes => yes ? getAnalytics(app) : null);
Try this one
import firebase from "firebase/app"
import "firebase/auth"
import "firebase/firestore"
import "firebase/storage"
import "firebase/analytics"
const firebaseConfig = {
apiKey: process.env.NEXT_PUBLIC_API_KEY,
authDomain: process.env.NEXT_PUBLIC_AUTH_DOMAIN,
projectId: process.env.NEXT_PUBLIC_PROJECT_ID,
appId: process.env.NEXT_PUBLIC_APP_ID,
storageBucket: process.env.NEXT_PUBLIC_STORAGE_BUCKET,
messagingSenderId: process.env.NEXT_PUBLIC_MESSAGING_SENDER_ID,
measurementId: process.env.NEXT_PUBLIC_MEASUREMENT_ID,
}
if (!firebase.apps.length) {
firebase.initializeApp(firebaseConfig)
}
// Auth export
export const auth = firebase.auth()
// Firestore exports
export const firestore = firebase.firestore()
export const serverTimestamp = firebase.firestore.FieldValue.serverTimestamp
export const fbTimestamp = firebase.firestore.Timestamp
export const fromMillis = firebase.firestore.Timestamp.fromMillis
export const increment = firebase.firestore.FieldValue.increment
// Storage exports
export const storage = firebase.storage()
export const analytics = () => {
if (typeof window !== "undefined") {
return firebase.analytics()
} else {
return null
}
}
export default firebase
ReferenceError: navigator is not defined
because there is no window object present during the server-side rendering of the Nextjs application.
Try:
if(typeof window != undefined){
firebase.analytics()
}
I just updated my firebase to version 9 and this error is not seen.
Update to version 9 could be a solution to this.
But for version 9, there are some changes in firebase declaration.
import firebase from 'firebase/compat/app'
import 'firebase/compat/auth'
import 'firebase/compat/firestore'
Using firebase V 9.16 this how I solved the issue
import { initializeApp } from "firebase/app";
import { getAnalytics, isSupported } from "firebase/analytics";
import { getFirestore } from "firebase/firestore"
const firebaseConfig = {
...
};
let app; let analytics; let db
if(typeof window != undefined){
app = initializeApp(firebaseConfig);
analytics = isSupported().then(yes => yes ? getAnalytics(app) : null);
db = getFirestore(app)
}
export {app, analytics, db}
In _app.js I import analytics and i use useEffect like
useEffect(() => {
analytics;
}, [])