I'm working on a React and Firebase project and I'm having trouble setting up the autocompletion on my code (I'm using VScode).
Here's what I've got so far:
HOW I'M PROVIDING FIREBASE TO MY APP COMPONENTS (VIA CONTEXT)
FirebaseContext.js
import React from 'react';
const FirebaseContext = React.createContext(null);
export default FirebaseContext;
firebase.js
import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';
import 'firebase/functions';
// .env file in root folder
const config = {
apiKey: process.env.FIREBASE_APP_API_KEY,
authDomain: process.env.FIREBASE_APP_AUTH_DOMAIN,
databaseURL: process.env.FIREBASE_APP_DATABASE_URL,
projectId: process.env.FIREBASE_APP_PROJECT_ID,
storageBucket: process.env.FIREBASE_APP_STORAGE_BUCKET,
messagingSenderId: process.env.FIREBASE_APP_MESSAGING_SENDER_ID
};
firebase.initializeApp(config);
firebase.functions().useFunctionsEmulator('http://localhost:5000');
export default firebase;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import firebase from './helpers/firebase/firebase';
import FirebaseContext from './helpers/firebase/FirebaseContext';
import { BrowserRouter as Router} from "react-router-dom";
...
ReactDOM.render(
// HERE'S HOW I'M PROVIDING FIREBASE FOR MY APP
<FirebaseContext.Provider value={firebase}>
<Router>
<App/>
</Router>
</FirebaseContext.Provider>
,document.getElementById('root')
);
HOW I'M CONSUMING FIREBASE IN MY COMPONENTS
AddProductContainer.js
import React, { useEffect, useState, useCallback, useContext } from 'react';
import FirebaseContext from '../../../helpers/firebase/FirebaseContext';
function AddProductContainer() {
const firebase = useContext(FirebaseContext);
function saveToFirestore() {
// I DON'T HAVE ANY AUTOCOMPLETION FROM 'FIREBASE...'
firebase.firestore().collection('products').add({
title: productDetails.title.newTitle,
description: productDetails.description,
categories: productDetails.categories
});
}
}
QUESTION
How can I get autocompletion from Firebase inside a JavaScript project?
Note: All of my component files are .js
. I'm not using Typescript.
Is there a way to use JSDoc annotations to get access to autocompletion in this case?
Something like:
/** @type {firebase} */
const firebase = useContext(FirebaseContext);
It would definitely be pretty tricky to do it the way you're doing it without Typescript or something, but can I suggest another option?
I don't think it's necessary to put the firebase
object itself in context. Putting app
in context might make sense (the object returned from firebase.initializeApp
) if you were going to use more than one app or just wanted to be explicit, but it seems like firebase
itself would make more sense being a direct import (import firebase from 'firebase/app'
) in any file that's using it. It won't create a second instance of firebase or anything if that's what you're concerned about, it's just a handle for the firebase library. It'll pick up the default app you initialized with firebase.initializeApp()
as long as initializeApp()
ran first. initializeApp()
creates a global default firebase app that any invocation of Firebase methods will pick up.
If you're uncomfortable with globals, you can be explicit about the specific app you're working with by assigning const app = firebase.initializeApp(...)
, then passing app
down through props or context, then always calling firebase packages with app
as an argument, such as firebase.firestore(app).collection('products').etc...
.
But there should be no cost to importing the firebase
package directly at the top of any file you're using it in (and want autocomplete in).