Reputation: 449
it's my firstime using Firebase and I think that I've followed all step to connect my project to firebase. I tried to run my project with a small js console.log(firebase)
When I went to my console I received this error message Failed to resolve module specifier "firebase/app"
I want to mention that I've create a node_module folder and I did npm i firebase.
html file:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>TP1</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/css/bulma.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
<script type="module" src="/index.js"> </script>
</head>
<body>
index.js:
import { initializeApp } from "firebase/app";
//import { getDatabase } from "firebase/database";
const firebaseConfig = {
//(my config...)
};
const app = initializeApp(firebaseConfig);
//const database = getDatabase(firebaseConfig);
console.log(firebase)
Upvotes: 10
Views: 18732
Reputation: 187
What you have defined in the imports of your index.js are npm paths. The browser wouldn't understand what these means unless they are bundled by webpack/rollup.
Therefore what you need to do is to convert the import paths to browser module paths as explained in this article.
So your index.js will look like this:
import { initializeApp } from "https://www.gstatic.com/firebasejs/10.7.1/firebase-app.js";
import { getFirestore } from "https://www.gstatic.com/firebasejs/10.7.1/firebase-firestore.js";
const firebaseConfig = {
//(my config...)
};
const app = initializeApp(firebaseConfig);
// To initialize database you need to pass app as a parameter of getFirestore
const database = getFirestore(app);
console.log(database)
To use the npm paths you need to use webpack/rollup as explained by other answers here.
I hope this helps.
Upvotes: 1
Reputation: 46
You have to use a bundler as said in other answers, so what you have to do is follow these module bundling steps.
After you get to the step where you run
npm run build
it will probably throw error. If the error says something like no index.html found then what you have to do is in "public" folder or whatever name you gave it when installing and seting up firebase, and move all to folder dist created in your root folder, and what i did is move src from "public" folder to root folder where you have all those config files like "webpack.config.js" and also in that file you have to change to something like this:
const path = require('path');
module.exports = {
// The entry point file described above
entry: './src/index.js',
// The location of the build folder described above
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
watch: true,
// Optional and for development only. This provides the ability to
// map the built code back to the original source format when debugging.
devtool: 'eval-source-map',
};
and then in firebase.json you have to set it up to something like this:
{
"hosting": {
"public": "dist",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}
after that you can run npm run build
if for some reason you couldnt get it to work you can watch this tutorial and follow it:
https://www.youtube.com/watch?v=vK2NoOoqyRo
Upvotes: 1
Reputation: 4466
The Firebase team designed their code to work with a bundler. In particular, note these sentences from the docs:
Module bundlers read import paths in your code and combine (bundle) your application-specific code with your imported library code.
From version 9 and higher, the Firebase JavaScript SDK is optimized to work with the optimization features of module bundlers to reduce the amount of Firebase code included in your final build.
I followed the easy-to-understand webpack example shown in the docs. My only change was in webpack.config.js, were I put bundle.js in the public directory rather than dist:
output: {
path: path.resolve(__dirname, 'public'), // change here
filename: 'bundle.js'
},
I do this because Firebase tends to put their web app code in a directory called public.
In public/index.html, near the bottom of the body tag, I use this code to load bundle.js:
<script src="bundle.js"></script>
I put it there because that file might take the longest to load, so I make everything else in index.html visible and then begin the potentially longer bundle.js load process.
After doing this the following code from my index.js file began to work:
import { initializeApp } from 'firebase/app';
Upvotes: 1
Reputation: 206
To run Firestore without Webpack or Rollup, skip the npm installs and replace the import lines with Firestore's browser module references. It's explained here:
https://firebase.google.com/docs/web/setup?sdk_version=v9&authuser=0 (in Step 2).
The video is helpful as well, and it explains Firebase's new (in V9) modular/functional vs. the deprecated object.method model.
Here's how my JS module for the Firestore connection to a web app I've developed for work:
// Import the functions you need from the SDKs you need
import { initializeApp } from "https://www.gstatic.com/firebasejs/9.1.1/firebase-app.js";
import { getFirestore } from "https://www.gstatic.com/firebasejs/9.1.1/firebase-firestore.js"
import { collection, getDocs, addDoc, Timestamp } from "https://www.gstatic.com/firebasejs/9.1.1/firebase-firestore.js"
import { query, orderBy, limit, where, onSnapshot } from "https://www.gstatic.com/firebasejs/9.1.1/firebase-firestore.js"
// 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 = {
apiKey: "xxxxxxxxxxxxxxxxxxxxxxxxx",
authDomain: "xxxxxx.firebaseapp.com",
projectId: "xxxx9",
storageBucket: "xxxxx.appspot.com",
messagingSenderId: "xxxxx",
appId: "1:xxx:web:xxx"
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);
export { app, db, collection, getDocs, Timestamp, addDoc };
export { query, orderBy, limit, where, onSnapshot };
Upvotes: 19
Reputation: 26171
When you use import { ... } from "some/package"
, you are expected to use a bundler like Webpack or Rollup to compile your code prior to accessing it on a website. This pulls the pieces you need out from your dependencies ready for use by your code.
Especially in v9+ of the SDK, the Firebase SDK was rewritten to support these bundlers, so expect many code examples you see to have been written for the now deprecated v8 or older. How to move this older code is covered in this migration guide.
A key takeaway from that guide is that firebase
is no longer a global object. As you are new to Firebase, I would avoid writing any code that uses the old syntax. You can spot older syntax by looking for code like firebase.initializeApp()
, firebase.database()
, firebase.firestore()
and so on. In the SDK those examples have been replaced by initializeApp()
, getDatabase()
and getFirestore()
respectively.
If you intend to use modular code directly in your browser (using <script type="module" src="..."></script>
), it is important to remember that the code is isolated from the browser console - you can't run console.log(firebaseConfig)
and expect it to have your object.
This next section is not for production code, just for trying things out in a familiar environment.
If you want to tinker around with the Firebase libraries in your browser console, you will add something similar to this:
<script type="module">
window.FIREBASE_MODULES = window.FM = {};
async function loadFirebaseModule(serviceName, sinkErrors) {
const name = serviceName.toLowerCase();
if (window.FIREBASE_MODULES[name]) return window.FIREBASE_MODULES[name];
try {
// uses unpkg to get the latest semver
if (!loadFirebaseModule.version) {
const response = await fetch("https://unpkg.com/firebase/firebase-app.js", { method: "HEAD" });
const match = /@\d+(?:\.\d+)*/.exec(response.url);
if (!match) {
console.log("Unexpected resource URL (SemVer could not be determined, falling back to v9.0.0): " + response.url);
loadFirebaseModule.version = "9.0.0";
} else {
loadFirebaseModule.version = match[0].slice(1);
}
}
// use the found semver to pull from Google's CDN
const module = await import(`https://www.gstatic.com/firebasejs/${loadFirebaseModule.version}/firebase-${name}.js`);
window.FIREBASE_MODULES[name] = module;
console.log(`Successfully imported "${name}" module`)
return module;
} catch (err) {
if (sinkErrors) {
console.error(`Failed to import "${name}" module`, err);
} else {
throw err;
}
}
}
window.loadFirebaseModule = loadFirebaseModule;
</script>
That little snippet will now allow you to run code like this either in-page or in the browser's console. It returns a Promise, so make sure to wait for it to finish resolving if you are using it inside a script.
loadFirebaseModule('app')
.then(({ initializeApp }) => {
initializeApp({ /* ... config ... */ });
});
loadFirebaseModule('storage');
loadFirebaseModule('storage', true); // import & ignore the error
Once a module is loaded, you can use const { getApp } = FM.app
similar to how you would use import { getApp } from "firebase/app"
.
Upvotes: 8