Adding firebase to the application
In the next phase, we will get to the core functions of the application. To use Firebase, we need to obtain authorization for Firebase to know who is accessing the Firebase functions. We need to generate a config object to use with the application.
To generate the config object, check out this guide.
Your final Firebase config object should look like this:
Authentication with email and password
Ensure you have enabled email-password authentication from your firebase console. From the console, go to Authentication (Sign in method tab) and enable Email/Password
Authentication with github
Ensure you have enabled Github authentication from your firebase console. From the console, go to Authentication (Sign in method tab) and enable Github.
Authentication with google (gmail) account
Ensure you have enabled authentication with Google from your firebase console. From the console, go to Authentication (Sign in method tab) and enable Google.
Building the server
The index.js file is the entry point of the application. It will also act as the server file for the project.
Creating the application routes
We need three routes for this project:
Errors
All errors have the following structure
Further readings
To find more about the topic, you can check the resources in the following links:
Id token authentication with firebase, node js (explained, github)
Let’s code now;
I suppose you have a client-side which you can make a request. It is not a must but the code will require it. First, start a Node js Server using Express js. Your server.js file should look like;
const express = require('express')
const app = express()
const port = 8080
const cors = require('cors');
app.use(cors());
app.use(express.json());app.get('/', (req, res) => res.send('Hello World!'))app.listen(port, () => console.log(`Example app listening on port ${port}!`))
Okay, the server is ready. Let’s make Firebase and connections ready.
You need to create a firebase project and enable email/password login authentication. Suppose you know it, I will skip this kind of part. Then get your Firebase Config JSON data. This is enough to use but you have to get the service account JSON file too because I am going to use admin functions. Put it in your project folder. You can check it online on how to get it. After you are done, create a fbConfig.js file. And configure your settings like;
require("firebase/auth");
const firebase = require('firebase')
const admin = require('firebase-admin')
const serviceAccount = require("YOUR SERVICE ACCOUNT JSON PATH");var firebaseConfig = {
//YOUR FIREBASE CONFIG
};firebase.initializeApp(firebaseConfig);
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "YOUR DATABASE URL"
});module.exports = { firebase, admin };
By the way, do not forget installing the required packages using npm.
Here I exported firebase and admin. The ‘firebase’ will do my login, signup, and logout. ‘admin’ will do my token stuff. Create another file named user.js to put our functions in. I will show here the login function to explain but you can find more on Github repository below. So you have to add a user to test manually on Firebase.
First, import this;
const { firebase, admin } = require('./fbConfig')
Then this;
exports.login = (req, res) => {firebase.auth().signInWithEmailAndPassword(req.body.email, req.body.password)
.then(function () {
firebase.auth().currentUser.getIdToken(true).then(function (idToken){
res.send(idToken)
res.end()
}).catch(function (error) {
//Handle error
});
}).catch(function (error) {
//Handle error
});
}
At the code above, signInWithEmailAndPassword is the function by Firebase to let you log in. You can log in with the help of express js middlewares like above. You can find out more on https://expressjs.com/en/guide/writing-middleware.html. As I explained token, after you logged in you have to get a token to carry. So inside the ‘.then’ function, I get an IdToken which is a unique token for each session and holds user info. Now all I have to do is send it back to the client. And sent it right in the ‘.then’ function.
If you want, you can create a custom token instead of using IdToken. You should replace inside the first ‘.then’ function with;
admin.auth().createCustomToken(uid)
.then(function (customToken) {
res.send(customToken)
res.end()
})
.catch(function (error) {
//Handle error
});
‘uid’ parameter is your logged-in user’s id. You can have it using firebase currentUser property. Great, the user is logged-in and given the token.
Before I continue, update your server.js file, add the code below;
const fbAuth = require('./fbAuth')const {
login,
userBasedFunc
} = require('./user')app.post('/login', login);
app.get('/userBasedFunc', fbAuth, userBasedFunc);
Now you will ask what is ‘fbAuth’. This function will return the user info if the token is valid. It will work right before userBasedFunc. Then you can access the returning value from userBasedFunc using middlewares. Create a fbAuth.js file and paste the code below;
const { firebase, admin } = require('./fbConfig');module.exports = (req, res, next) => {const token = req.header('Authorization').replace('Bearer', '').trim()var user = firebase.auth().currentUser;
if (user) {
admin.auth().verifyIdToken(token)
.then(function (decodedToken) {
if(decodedToken.uid === user.uid)
{
req.user = user.uid
return next()
}
}).catch(function (error) {
//Handle error
});
} else {
console.log("There is no current user.");
}
};
‘verifyIdToken’ will check the token with the currentUser and return you the user, if it is valid. WARNING: This function will not work if you use the custom token instead of IdToken, you should use a custom token decoder. So, next() is the middleware to carry the data to the called function. All you have to do is, writing ‘req.user’ to access the data in userBasedFunc.
Here is a thing I should inform about, ‘req.header’. This is to receive the token. You should send the token to the server in the authorization header of your call.
Prerequisites
To follow this artice along with me effectively:
Project setup
We will set up the project just like any other Node.js project. Execute the command below to get started.
Register a callback
You can register a callback to perform other operations after token verification or customize responses on token verification error.
When using a callback, remember to call next() or respond with an error after processing the information returned to the callback
const middlewareCallback = function(req, res, next, error, data) {
if (error === 'ERROR_NO_TOKEN') {
// token not supplied
res.status(401).json({error: "No token provided"});
}
else if (error === 'ERROR_INVALID_TOKEN') {
// token failed verification
res.status(401).json({error: "Unauthorized access"});
}
else if (error) {
// some other error occurred (this should never happen!)
res.status(500).json({error: "Unexpected error"});
}
else if (data.error) {
// there was no error with verifying the token, thus user id can be found in data.userId
// there was however an error in getting user info from firebase using the id
res.status(401).json({error: "An error occurred while trying to verify your credentials"});
}
else {
// data contains user id and token (v0.2.0 and later) and full user information (id, displayName, email etc) for v0.1.1 and earlier
req.user = data;
next();
}
};
const firebaseTokenMiddleware = FirebaseAuth.initTokenMiddleware(serviceAccount, middlewareCallback); // v1.0.0 and later
const firebaseTokenMiddleware = new FirebaseAuth.Guard(serviceAccount, middlewareCallback); // v0.2.0 to 0.9.9
const firebaseTokenMiddleware = firebase.protect(serviceAccount, middlewareCallback); // v0.1.1 and earlier
Starting the server
In this phase, we will test our application by running the command nodemon start in the terminal.
We need to add the below code in the index.js file:
Step 1 – get service account json from your firebase project console
From your console, go to Project Overview -> Settings icon -> Project settings (Service Accounts tab)
Import the dependencies
To bring in the dependencies, add the snippets below to your index.js file.
Step 2 – initialize token checking middleware for express
Setup default token middleware with following behaviour