When we need realtime database which allows us to store and synchronize data across multiple platforms, one of most known possibilities will be Firebase.
In this example we will use JavaScript libraries provided by Google to describe case when we try to integrate it with existing application. It’s common situation, when we don’t want to abandon our application and migrate all users data to new service. Fortunately with help of firebase and firebase-admin npm libraries this task becomes quite easy. Configure Firebase package with params from console under Internet configuration https://console.firebase.google.com/project//authentication/users
var config = {
apiKey: <api key>,
authDomain: <auth domain>,
databaseURL: "https://<my_project>.firebaseio.com",
storageBucket: <storage bucket>,
messagingSenderId: <sender id>
};
// Frontend
function getToken(){
return fetch(
'https://myapp.com/auth/token/',
{
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
login: 'mylogin',
password: 'secretpassword'
})
}
)
}
//Backend
var firebaseAdmin = require('firebase-admin');
firebaseAdmin.initializeApp({
credential: firebaseAdmin.credential.cert('cert.json'),
databaseURL: 'https://<my_project>.firebaseio.com'
});
cert.json is path to file with certificate obtained in Firebase console in projects settings/service accounts: https://console.firebase.google.com/project//settings/serviceaccounts/adminsdk Next we create endpoint which will respond to call.
// Backend
var firebaseAdmin = require('firebase-admin');
var express = require('express');
var router = express.Router();
var authenticate = require('my-authentication-library');
router.post('/token', function(request, response, next) {
if(authenticate(request)){
firebaseAdmin.auth().createCustomToken(request.body.login).then(function(token){
response.json({ token: token });
})
.catch(function(error) {
res.status(500).json({error: "Error during token creation"});
});
} else {
res.status(401).json({error: "Invalid login or password"});
}
});
module.exports = router;
var authRoute = require('./auth_route.js');
app.use('/auth', authRoute);
function authorizeAndQuery(responseData){
firebase.auth().signInWithCustomToken(responseData.token)
.then(function(user_login){
var myRef = firebaseApp.database().ref('firebase_data');
myRef.once('value', function(snapshot) {
console.log(snapshot.val());
});
});
}
Some important tips:
- time on host with backend has to be synced (for example with ntpd). Too big difference between real time and host time will cause generated custom tokens invalid
- when importing certificate there is possibility to add them to environment (with for example dotenv). However we have to be aware if newline characters are passed correctly. As in previous tip, it will result in invalid tokens
- by default token will expire in 1 hour. In that kind of Firebase response we should refresh it. In order to do it second api endpoint will be needed. New token can be generated with https://firebase.google.com/docs/reference/js/firebase.User#getToken