Search code examples
javascriptnode.jsgoogle-cloud-firestoregeofirevite

import geofire-common with firestore for browser code


I'm a bit confused trying to use geofire-common in browser code.

In the beginning, I've made a successful attempt with NodeJS which uses geofire-common referenced here in the Google documentation and which code looks like this:

import { createRequire } from 'module'; // <------ trick to get a require function
const require = createRequire(import.meta.url);

const { initializeApp, cert } = require('firebase-admin/app');
const { getFirestore } = require('firebase-admin/firestore');

const serviceAccount = require('./serviceAccountKey.json');

initializeApp({
  credential: cert(serviceAccount),
});

const db = getFirestore();
const geofire = require('geofire-common'); //<---------- geofire-common

Then, I wanted to make this work from the browser side... and I stumbled uponthis example. In this example, I can see a 'require' function so I guess it has something to do with old school commonJS module:

const geofire = require('geofire-common');

Require is not part of the standard JavaScript API and should be NodeJS specific (which is a bit strange because i thought the example was browser code), so I've tried to use an ES6 import..

import {geofire} from 'geofire-common';

... without success :

The requested module '/node_modules/.vite/geofire-common.js?v=738ba8db' does not provide an export named 'geofire'

If some of the JS experts around would be willing to shed some light about those 2 packages and help me to correctly import geofire if it's possible, that would be much appreciated.


Solution

  • That is a very interesting question, once I got into it, it was kind of confusing, since the imports used in JavaScript have changed, and there are a few differences depending on the use case.

    First, we need to know where this Geofire module comes from; you mentioned the documentation and the example where we can see they use the command line to install this library:

    // Install from NPM. If you prefer to use a static .js file visit
    // https://github.com/firebase/geofire-js/releases and download
    // geofire-common.min.js from the latest version
    npm install --save geofire-common
    

    As you can see, they are using NPM, which points to us that this is a nodejs library. This is important because you were confused about the origin and if it was a commonjs module, which it seems to be. This also means it should be called using require, a function and also this cause not to work when using import, which can be used only for ES modules style, as quoted from the node documentation:

    require

    The CommonJS module require always treats the files it references as CommonJS.

    Using require to load an ES module is not supported because ES modules have asynchronous execution. Instead, use import() to load an ES module from a CommonJS module.

    Then you asked how to run this code on the browser side, which I think can be done using the HTML reference or downloading the js file as suggested in the github repo.

    Alternatively, you can include GeoFire in your HTML. To do so, download a minified or non-minified version of GeoFire from the releases page of this GitHub repository. Then, deploy it to Hosting in your Firebase project.

    <!-- Firebase -->
    <script src="https://www.gstatic.com/firebasejs/8.0.1/firebase-app.js"></script>
        <script src="https://www.gstatic.com/firebasejs/8.0.1/firebase-database.js"></script>
    
    <!-- GeoFire (TODO: substitute in your own project id)-->
    <script src="https://my-firebase-project.web.app/geofire-5.0.1.min.js"></script>
    

    I would also refer to the API Reference for further guidance, I can see some differences on how to use the library between the firebase page and the API reference.

    Finally, in the npm page we can see geofire as a dependent of geofire-common, and both have the same github repository, so I guess it has something more to do with the naming. I would say both are basically the same.