How can i checking if the user is logged? - node.js

i am checking if the user is logged
const firebase = require('firebase-admin')
firebase.auth().onAuthStateChanged((user) =>{
console.log('message1', user)
if (user) {
console.log('exist')
} else {
console.log('not exist')
}
});
but i only get error: Error: FIREBASE_ERROR

You are using the Admin SDK, which has no concept of a signed-in user. All code in the Admin SDK runs under an administrative account, not under a Firebase Authentication user's credentials.
If you want to determine what user is logged in on a client, that is then communicating with the process that runs the Admin SDK, you can do so by getting the ID token for the user on the client, sending that to the server, and decoding and verifying the ID token on the server.
Also see:
Node.JS Firebase Auth - Is there a way to keep a user session like with client side Firebase Auth?
How to check if user is authenticated in Firebase and Express/Node.js?

Related

Method Creating custom tokens will create uid if not exist in firebase

I using firebase. I using method: Creating custom tokens. When i look document in firebase https://cloud.google.com/identity-platform/docs/admin/create-custom-tokens .
const uid = 'some-uid';
admin
.auth()
.createCustomToken(uid)
.then((customToken) => {
// Send token back to client
})
.catch((error) => {
console.log('Error creating custom token:', error);
});
I have a question
If i don't have uid in firebase, it will create it ? If i have uid, i only create custom token and send back to client. I look document and i don't see document specific it. Thanks
There is no need to make an API call to create a user in Firebase when you're using custom authentication. Calling createCustomToken on the server, and then signing on the client with the resulting ID token, is all that is needed.
There is no separate step to create the UID for a custom provider. You create the custom token with the UID and other claims you want, send it to the client over a secure connection, and the client can then sign in to Firebase with that token.
For Firebase services the ID token, and the UID in it, are ephemeral - since it is your server (where you run the Admin SDK), and the client that maintain them. That's the reason a separate step to create the UID in Firebase is not necessary.

Single user is being logged in across all devices

I was building a project on node.js recently, I came across this bug of user authentication. The problem is that after I log in from one account, if at the same time I refresh the home page of the website from another device, it redirects to the dashboard of the first user account. In other words, a single user is getting logged in on all the devices over the network. If suppose I don't refresh the page, and I log in normally on the application, it works fine. This problem is happening, both on the localhost as well as after hosting it on Heroku. Technologies used- node.js for handling back-end views and URLs. HTML, CSS, JavaScript for the front-end. Firebase for the database and authentication. Here is the code for the login part-
const express = require("express");
const path = require("path");
//Create Router Object.
const router = express.Router();
//Main Login Page (GET)
router.get("/", (request, response) => {
response.sendFile(path.resolve("./views/html/login.html"));
});
//Main Login Page (POST)
router.post("/", (request, response) => {
let email = request.body.email;
let password = request.body.password;
firebase.auth().setPersistence(firebase.auth.Auth.Persistence.NONE);
firebase.auth().signInWithEmailAndPassword(email, password)
.then(r => {
let user = firebase.auth().currentUser;
if (user.emailVerified)
response.redirect('/dashboard');
else
response.send("<h1>Please Verify your email address.</h1>");
})
.catch(error => {
console.log(error);
response.send("<h1>Invalid Credentials</h1>");
});
});
Please can someone help me by resolve this bug in my project?
Calling firebase.auth().signInWithEmailAndPassword(email, password) signs the user in on the location wherever you call this code. Since you run this in an express.js app in Node.js, the user is signed in to that Node.js process, until you sign them out again. This is why the Firebase Authentication SDK you are using is only meant to be used in client-side applications, where this behavior is working as intended.
When integrating Firebase Authentication in a server-side process, you should use the Firebase Admin SDK. This Admin SDK has no concept of a currently logged in user, and no signInWithEmailAndPassword. Instead, if you need to know the identity of the user accessing the server-side code, you'll:
Sign the user in in their client-side app with the Firebase Authentication SDK.
Get the ID token for that user on the client, and pass that with your call to the server.
On the server, verify that ID token, to ensure the user is who they claim they are.
Then use the information on the user's identity to determine if they're authorized to access the information.
For more on this, see the Firebase documentation on verifying ID tokens.

firebase.auth().currentUser returning null

In the html file that I have for the sign-in page, I perform the authentication using Firebase and on successful authentication, I redirect the given user to the homepage. When I call firebase.auth().currentUser in the express file, I use for rendering and routing pages, I get undefined or null for the current user.
Can anyone help me understand what the issue might be?
This is how I perform the authentication:
firebase
.auth()
.signInWithEmailAndPassword(temail, tpass)
.then(function(firebaseUser) {
window.location.href = "http://localhost:5000/homepage";
})
.catch(function(error) {
window.alert("incorrect pass");
});
This is the code that I have in my express file:
app.get("/homepage", (req, res) => {
var user = firebase.auth().currentUser;
console.log("USER IS " + user);
res.render("menu", { title: "Welcome" });
});
Backend code doesn't have a sense of "current user". When you sign in on the frontend, the current user is only known on that client. It isn't known on the backend. If you want the backend to know which user is signed in, the client will have to send an ID token to the backend for it to verify. The documentation for the Firebase Admin SDK is used for that on the backend. The client must send the ID token to in the request to your route, and the code handling that route must verify the token in order to know the user that made the request. From the documentation:
If your Firebase client app communicates with a custom backend server, you might need to identify the currently signed-in user on that server. To do so securely, after a successful sign-in, send the user's ID token to your server using HTTPS. Then, on the server, verify the integrity and authenticity of the ID token and retrieve the uid from it. You can use the uid transmitted in this way to securely identify the currently signed-in user on your server.
When the user lands on a new page, Firebase automatically restores their previous authentication state. But to do so, it may have to contact the server, which means that it may take a few moments. While Firebase is restoring the state, auth().currentUser will be null.
To ensure you get the correct authentication state, you should use an authentication state listener, as shown in the documentation on getting the current user:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
} else {
// No user is signed in.
}
});

Firebase Admin SDK - Current Logged In User - Nodejs

How do i get currentUser in firebase admin SDK. In client SDK we can use
onAuthStateChanged() or firebase.auth().currentUser()
In NodeJs Server.js file firebase admin SDK onAuthStateChanged() Do not work, what should work here?
Basically i want only logged in users to access my innerPages so i am using express,nodejs app.get method to create routes.
app.get('/', authenticationRequired ,function(req,res){
res.sendFile(path.join(__dirname+'/index.html'));
});
And trying to write authenticationRequired method (returns false or true depending on if user is logged in).
The Firebase Admin SDK does not inherently know what user is using your Express web app. You will need to implement code for this. If you're already using Firebase Authentication in the web app, this takes these steps:
Retrieve the user's ID token on the client
You can get a user's ID token by using the firebase.auth().currentUser.getIdToken() method.
Pass this token from the client to the server
Verify the token on the server
The user ID token can be verified using the admin.auth().verifyIdToken(idToken) method. On success it will return a promise with the decodedToken, otherwise it will return a rejected promise.

NodeJS authentication with Firebase

I would like to authenticate and keep sessions via NodeJS with Firebase. Client can't directly communicate with Firebase.
In short:
Client (browser) <----> NodeJs(firebase-admin) <----> Firebase
I created Firebase client in NodeJS, then I used login method:
var firebaseClient = require('firebase');
firebaseClient.initializeApp(config)
firebaseClient.auth().signInWithEmailAndPassword(req.body.email, req.body.password).catch(function(error){
console.log(error);
})
and then I created route to check authenticated user:
app.get('/check',function(req,res){
var user = firebaseClient.auth().currentUser
console.log(user)
})
This method only allows me keep 1 previously logged user.
I would like to use firebase-admin, but I don't know how to keep session and authenticate users
You can authenticate clients on their respective devices/browsers using the client SDK, and them get them to send an ID token to a backend service written using firebase-admin (the admin SDK). The admin SDK provides methods for validating ID tokens sent by clients: https://firebase.google.com/docs/auth/admin/verify-id-tokens

Resources