In this article, I wanna bring a solution to embed and use Firebase and it’s services in WeWeb, as of today, that’s not possible without some custom code, as the WeWeb’s NPM plugin doesn’t seem to support the Firebase’s library.
Embedding the JavaScript into WeWeb
To be able to embed Firebase and it’s modules into WeWeb, we’re gonna use the platform’s biggest strength, which is the possibility to add and run custom JavaScript. In order to properly initiate our snippets, we’re going to be using a handy tool from the friends from Statechange, big props to them! This tool will allow us to get an embeddable snippet, that fits in the fairly complex lifecycle of a WeWeb application, with the respect of the fact that the editor is running as an iframe.
Composing our script
Before we can embed anything, we’ll naturally need something we actually can embed. In this part, I will be walking you through the whole process of setting up the JavaScript necessary to make this happen. From now on, I will be referring to “docs”, by which I mean the official Google’s Docs about Getting started with Firebase, in our case with Firestore. Specifically we’ll be following the Modular API reference.
// First we import the basic app
import { initializeApp } from 'https://www.gstatic.com/firebasejs/10.12.2/firebase-app.js'
// Then we import our desired modules (services)
import { collection, getFirestore, getDocs } from 'https://www.gstatic.com/firebasejs/10.12.2/firebase-firestore.js'
First, we will need to import our modules, in my case I’ll be importing two of them for illustration purposes. The first one, being the base Firebase’s initializeApp
, the next thing we’ll need is the getFirestore
which will allow us to initiate the Firestore as well. In the end I’m also importing some utilities, that I’ll use later, such as collection
and getDocs
.
// Prepare a reference to WeWeb's window
const _window = wwLib.getFrontWindow();
// Prepare the firebase Object
_window.firebase = { utils: { firestore:{} }, instances: {} };
// Hook up the Firebase's imports to our window
_window.firebase.utils.initializeApp = initializeApp;
_window.firebase.utils.getFirestore = getFirestore;
Next up goes some “prep work”, in order to be able to use the Firebase and Firestore instances globally within our project, we’ll need to hook them up to our app’s window
object. For the sake of keeping things organized, I’m initializing a dummy object with some properties, to which then we’ll add our instances and other utilities, as you can see with the initializeApp
and the getFirestore
.
// Your web app's Firebase configuration
const firebaseConfig = {
apiKey: "AIzaSyBlJHU...",
authDomain: "your-project.firebaseapp.com",
projectId: "your-project",
storageBucket: "your-project.appspot.com",
messagingSenderId: "439352359094",
appId: "1:439...:web:aeb6..."
};
An another thing, without which this whole script won’t work, is your Firebase’s configuration, you either will be prompted to copy this when you create your project, or you can simply retrieve it in your Firebase Dashboard, under the project’s settings tab.
// Initialize Firebase and Firestore
_window.firebase.instances.app = _window.firebase.utils.initializeApp(firebaseConfig);
console.log("Firebase App Initialized!");
_window.firebase.instances.fireStore = _window.firebase.utils.getFirestore(_window.firebase.instances.app);
console.log("Firestore Initialized!");
Now that we have the preparations out of the way, we can finally get our hands dirty and start initializing and calling stuff! First we’ll initialize the Firebase’s base instance via the initializeApp()
method and we store it in our window’s instances object, as an app
variable. This will allow us to initialize Firestore’s instance as well via the getFirestore()
method to which we pass our previously initiated app’s instance.
// Hook up the Firebase's methods we'll be using
_window.firebase.utils.firestore.collection = collection;
_window.firebase.utils.firestore.getDocs = getDocs;
Finally, we add the previously imported utilities, in our window’s utils
object so they’re ready anytime we need them.
Making our script embeddable, and embedding it in WeWeb
Now that we have our script ready, the only thing that remains is to slap it into the editor’s Custom JavaScript Block and it should work, right? Well not exactly, it’s a little bit more complex due to the nature of WeWeb’s inner workings, but we have a fix to that.
We’ll be transforming our script via this handy tool from the friends from Statechange. We can take our whole script, and place it into the text area, as also explained in the tutorial you can find on the page, it’s as simple as copying and pasting the code and then copying it again though.
Once our script is successfully transformed, it should look something like the following:
if(!window["scp-loading-e6b51ece-79ff-48b2-9b18-8488f8bd634b"]) {
window["scp-loading-e6b51ece-79ff-48b2-9b18-8488f8bd634b"] = true;
let doc;
/* Adding script from null */
doc = document.createElement('script');
doc.type = 'module';
doc.innerHTML = `
// First we import the basic app
import { initializeApp } from 'https://www.gstatic.com/firebasejs/10.12.2/firebase-app.js'
// Then we import our desired modules (services)
import { collection, getFirestore, getDocs } from 'https://www.gstatic.com/firebasejs/10.12.2/firebase-firestore.js'
// Hook the firebase to the window
const _window = wwLib.getFrontWindow();
_window.firebase = { utils: { firestore:{} }, instances: {} };
_window.firebase.utils.initializeApp = initializeApp;
_window.firebase.utils.getFirestore = getFirestore;
console.log("Firebase imported");
// Your web app's Firebase configuration
const firebaseConfig = {
apiKey: "AIzaSyBlJHU...",
authDomain: "your-project.firebaseapp.com",
projectId: "your-project",
storageBucket: "your-project.appspot.com",
messagingSenderId: "439352359094",
appId: "1:439...:web:aeb6..."
};
// Initialize Firebase
_window.firebase.instances.app = _window.firebase.utils.initializeApp(firebaseConfig);
console.log("Firebase App Initialized!");
_window.firebase.instances.fireStore = _window.firebase.utils.getFirestore(_window.firebase.instances.app);
console.log("Firestore Initialized!");
// Firestore utilities
_window.firebase.utils.firestore.collection = collection;
_window.firebase.utils.firestore.getDocs = getDocs;
`;
document.body.appendChild(doc);
}
Once we have this snippet of code transformed, we finally can go to WeWeb and add an On app load workflow, the On app load should be enough, as we need to initialize it only once in or app, but if there may be any issues, you can try switching to On page load as well. In this workflow, we’ll add a Custom JavaScript block, where we’ll simply copy and paste our snippet from Statechange.
Once you refresh the app, you should be able to see in the browser’s console our logs, telling us that Firebase and it’s modules are indeed initialized. The console should also tell you, if something’s wrong, as in my case there was a typo, where instead of getDocs
, I typed somewhere addDocs
.
Using Firebase and Firestore in WeWeb
Congratulations! The hardest part is behind us, we successfully done all the hard work, and now we can use the Firebase within our app, but you may ask how? The process is very similar to using the Supabase’s instance that WeWeb also provides within their wwUtils
utility object. In our case, we can use the Firebase’s instance by calling it from our window.
const firebase = wwLib.getFrontWindow().firebase.utils.firestore;
const db = wwLib.getFrontWindow().firebase.instances.fireStore;
const users = firebase.collection(db, context.parameters['collection']);
With this knowledge, we can call it anywhere in or app within any Custom JavaScript code block simply by referencing it from our window, and using it.
An example of how to use Firestore in a WeWeb app – fetching our documents
In case you are still a little confused, let me give you an example, we’re gonna fetch some data from our Firestore instance by using the following code snippet which is basically our WeWeb adaptation of what Firebase Docs suggest for fetching multiple documents.
const firebase = wwLib.getFrontWindow().firebase.utils.firestore;
const db = wwLib.getFrontWindow().firebase.instances.fireStore;
const users = firebase.collection(db, context.parameters['collection']);
const querySnapshot = await firebase.getDocs(users);
let result = [];
querySnapshot.forEach((doc)=> result.push({id: doc.id, data: doc.data()}))
return result;
By using this within our app with a reusable Workflow, we can make our own no-code “wrapper” around the Firebase’s SDK and effectively turn it into a no-code library similar to Supabase, or Xano. You can see in the left bottom corner where the console is, that when we test the Workflow, it runs and returns us the items.
Conclusion
To conclude this, all I can say, that WeWeb once again demonstrates that it’s capable of working coupled with anything we throw at it, even though it’s not always as straight forward as it could be. Firebase is an amazing product, and I’m eagerly going to be waiting to see how you guys implement it in your projects, now that you know how to do the hard part!
As usually, I encourage you to try this out, see how it goes, and if you get stuck, don’t forget! It’s doable, you just read it is, and it’s a part of your low-code learning process. See you at the next one!