javascriptfirebase

Uncaught SyntaxError: Cannot use import statement outside a module (Using Firebase)


I'm having a problem storing data to my database through my html form, The error I get comes from my import statement which is: Uncaught SyntaxError: Cannot use import statement outside a module!

Code below:

import {
  initializeApp
} from "firebase/app";
const firebaseConfig = {
  apiKey: "MY_API_KEY", //actual values are in my code, changed here for security purposes.

  authDomain: "My_auth_Domain",
  databaseURL: "FirebaseDb_URL",
  projectId: "Project_id",
  storageBucket: "storageBucket",
  messagingSenderId: "SenderId",
  appId: "appId"
};



const app = initializeApp(firebaseConfig);


let inviteInfo = firebase.database().ref("inviteinfos");


document.getElementById("#regform", submitForm);

function submitForm(e) {
  let name = document.getElementsByName("fullname").value;
  let compName = document.getElementsByName("compName").value;
  let email = document.getElementsByName("email").value;
  let address = document.getElementsByName("address").value;
  let contact = document.getElementsByName("contact").value;
  console.log(name, compName, email, address, contact);

  saveContactInfo(name, compName, email, address, contact);
  document.getElementById("#regform").reset();
}

What I have tried so far:

  1. changed import statement to the following
const {initializeApp} = require("firebase/app");
  1. used import with firebase provided link
import { initializeApp } from "https://www.gstatic.com/firebasejs/9.6.6/firebase-app.js";
  1. used const with the firebase provided link:
const {initializeApp} = require("https://www.gstatic.com/firebasejs/9.6.6/firebase-app.js");
  1. Moved js from app.js into the main html page with a script tag of type module.
  2. used npm to install firebase to retrieve the modules.
  3. in regards to the link based solution I tried to remove the -app to see if it made a difference but it did not.

So far none of these have worked for me, the table I am trying to store information to currently does not exist but research has shown that running even without the table existing will create the table automatically for me.


Solution

  • Load app.js like this:

    <script type="module" src="./app.js"></script>
    

    Inside app.js, you import firebase-app like this:

    import { initializeApp } from "https://www.gstatic.com/firebasejs/9.6.6/firebase-app.js";
    // ...
    

    Here's an example (I can't use a separate file for app.js, but this demonstrates that it does work):

    <script type="module">
    import { initializeApp } from "https://www.gstatic.com/firebasejs/9.6.6/firebase-app.js";
    // Check that it worked and returned a function:
    console.log(typeof initializeApp); // "function"
    </script>

    You don't need a script tag for firebase-app.js at all, it'll get loaded by the browser because of your import.

    Note that this will be using modules natively in the browser. All modern browsers directly support doing that, but obsolete ones like Internet Explorer don't, and separately loading modules like this can involve lots of small HTTP calls rather than a few larger ones, which can cause page load delays even with modern net protocols like SPDY. For that reason, people often use bundlers like Vite, Rollup, Webpack, etc. that combine modules into a small number of bundle files. If you like, you could look at doing that. But again, modern browsers natively support modules, so you don't have to.


    Using "https://www.gstatic.com/firebasejs/9.6.6/firebase-app.js" in every place you want to import from firebase-app may be a bit of a pain. You have two options to make it easier:

    1. In most modern browsers you can use an import map:

    <script type="importmap">
    {
        "imports": {
            "firebase/app": "https://www.gstatic.com/firebasejs/9.6.6/firebase-app.js"
        }
    }
    </script>
    

    That tells your browser that when you import from "firebase/app", it should use "https://www.gstatic.com/firebasejs/9.6.6/firebase-app.js".

    Live Example:

    <script type="importmap">
    {
        "imports": {
            "firebase/app": "https://www.gstatic.com/firebasejs/9.6.6/firebase-app.js"
        }
    }
    </script>
    
    <script type="module">
    import { initializeApp } from "firebase/app";
    // Check that it worked and returned a function:
    console.log(typeof initializeApp); // "function"
    </script>

    2. If you can't use import maps, you can write a module that re-exports everything from firebase-app, and then import from that module in your code rather than directly from firebase-app:

    Your own local firebase-app.js file:

    // This re-exports all of its named exports (but not its default, if any)
    export * from "https://www.gstatic.com/firebasejs/9.6.6/firebase-app.js";
    /* firebase-app.js doesn't provide a default export. If it did, this is
       how you'd re-export it:
    export { default } from "https://www.gstatic.com/firebasejs/9.6.6/firebase-app.js";
    */
    

    Then app.js would use firebase-app.js:

    import { initializeApp } from "./firebase-app.js";
    

    (I can't do a live example of that with Stack Snippets, but here's that on CodeSandbox.)