This page explains step by step how to configure, deploy and host a website with dynamic URLs on Firebase.
Before starting, I really struggled to write this page. The FireBase doc is not very clear. At the time I did my research, I didn't find any blog or video that clearly explained how to create dynamic URLs on FireBase. If this page helps you and saves you time, a little message or a donation, it will make me really happy !
The guide presented on this page has been tested with the following versions:
We assume that Node.js and npm are already installed. In my case, I used Volta with which you can select a Node engine when switching between projects.
If you are new to FireBase, I recommand to start by this page that explains to create a static website. Since this guide extends the previous, I strongly recommand to already understand the basics or FireBase.
The first thing to do is to create a Firebase account and project.
As it is already explained here, I will pass quickly.
The project ID (fir-dynamic-c68ee
in my case) is provided.
We'll need it later, but don't worry, it is easy to retreive the ID in the Firebase console.
Create new folder on your local machine to store your project. Open a terminal an go to your new folder. Run the following command to install the Firebase package:
npm install firebase
If Firebase CLI tools are not installed yet, run the following command:
npm install -g firebase-tools
This command installs the Firebase tools globaly, so the content of your project folder should not change.
Login to your Firebase account:
$ firebase login
The project is created in two steps:
To create and initiate the project, run the following command from your project's root directory for initiate the hosting:
firebase init hosting
The above command should display something like:
$ firebase init hosting
######## #### ######## ######## ######## ### ###### ########
## ## ## ## ## ## ## ## ## ## ##
###### ## ######## ###### ######## ######### ###### ######
## ## ## ## ## ## ## ## ## ## ##
## #### ## ## ######## ######## ## ## ###### ########
You're about to initialize a Firebase project in this directory:
/home/project/firebase-dynamic
=== Project Setup
First, let's associate this project directory with a Firebase project.
You can create multiple project aliases by running firebase use --add,
but for now we'll just set up a default project.
? Please select an option: (Use arrow keys)
❯ Use an existing project
Create a new project
Add Firebase to an existing Google Cloud Platform project
Don't set up a default project
Select Use an existing project
and the Firebase project you created previously.
? Please select an option: Use an existing project
? Select a default Firebase project for this directory: fir-dynamic-c68ee (firebase-dynamic)
i Using project fir-dynamic-c68ee (firebase-dynamic)
Few more questions are asked, here are my answers:
? What do you want to use as your public directory? public
? Configure as a single-page app (rewrite all urls to /index.html)? No
? Set up automatic builds and deploys with GitHub? No
✔ Wrote public/404.html
✔ Wrote public/index.html
A new public folder should be create with a default index.html
file.
To be sure everything is properly installed, you can deploy your static part:
firebase deploy
The last line contains the public URL of your project.
The phylosophy of Firebase is that some URL will be redirected to functions. You now have to initialize Cloud Functions with the following command:
firebase init functions
Answer the questions, then the tool install the files we'll need:
? What language would you like to use to write Cloud Functions? JavaScript
? Do you want to use ESLint to catch probable bugs and enforce style? Yes
✔ Wrote functions/package.json
✔ Wrote functions/.eslintrc.js
✔ Wrote functions/index.js
✔ Wrote functions/.gitignore
Install dependencies with npm.
You should now have a new folder functions
in your project directory.
Latter, dynamic URLs will be redirected to our function. Let's start by writing anapp
function:
// Firebase functions
const functions = require("firebase-functions");
// Create an app with Express
const express = require("express");
const app = express();
// Any URL starting with /app/id will call this function
app.get("/", (req, res) => {
res.send("This is a function");
});
// Export the app
exports.app = functions.https.onRequest(app);
To test your function, you can run firebase deploy
in the command line, but we will first try it localy.
You probaly noticed that the Firebase CLI tool create a package.json
file in the functions
folder.
Move to the functions
folder, and run npm install
.
To the root folder of your project, run the following command to serve your functions localy:
firebase serve
This command creates two local servers on your computer. The first one is your local hosting:
✔ hosting[fir-dynamic-c68ee]: Local server: http://localhost:5000
The link should display the default index.html
in the public
folder;
The second link is your functions folder:
✔ functions[us-central1-app]: http function initialized (http://localhost:5001/fir-dynamic-c68ee/us-central1/app).
This last link should display:
This is a function
Your function is working properly. Note that the /app
at the end of the URL specify which function is called.
Here, we just have a single function app
.
From here, we have two problems:
This is the tricky part!
To serve dynamic URL, we will edit the firebase.json
file in the project root.
The file should look like:
{
"hosting": {
"public": "public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
]
}
}
Add the following lines to specify that any URL starting with /app/
will be redirected to our app
function`
{
"functions": [
{
"source": "functions",
"codebase": "default",
"ignore": [
"node_modules",
".git",
"firebase-debug.log",
"firebase-debug.*.log"
]
}
],
"hosting": {
"public": "public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "/app/**",
"dynamicLinks": true,
"function": "app"
}
]
}
}
The first part configures the functions, the last part specifies that any URL starting with /app
will be redirected to our function.
Note that the first part may be add by the previous command firebase init functions
.
Edit the index.js
in the functions
folder, and change the app.get()
first parameter:
// Firebase functions
const functions = require("firebase-functions");
// Create an app with Express
const express = require("express");
const app = express();
// Any URL starting with /app/id will call this function
app.get("/app/:id", (req, res) => {
res.send("ID = " + req.params.id);
});
// Export the app
exports.app = functions.https.onRequest(app);
In your browser, go to the root URL of your static hosting.
If you didn't change the file index.html
, you should have a page titled Firebase Hosting Setup Complete
.
At the end of the URL, add /app/12
, in my case: http://localhost:5000/app/12:
Note that the last parameter of the URL (12) is sent to the Express get()
function.
You can now deploy your app to check it is still working once deployed.
Functions are not working with the free plan. Check that your project is with the blaze plan. If not, you'll have to upgrade your project in the Firebase console.
Run the following command to deploy on Firebase hosting:
firebase deploy
It may take some time, especialy when creating the Node.js 18 functions. Be patient!
i functions: creating Node.js 18 function app(us-central1)...
Note that you Node.js version may prevent the command to work properly.
If necessary, change the version in the package.json
file:
"engines": {
"node": "18"
},
Once the command is over, the last line should display your public URL:
Hosting URL: https://fir-dynamic-c68ee.web.app
Go to this URL, you should have one more time your home page index.html
.
As previously, add /app/7
at the end of the URL: https://fir-dynamic-c68ee.web.app/app/7
Et voila:
You can download the final project on Github: