user logged globally in Firebase/Node.js - node.js

I am having a problem with Firebase.
I am trying to use the Node.js (Client), meaning that I am initializing the SDK on Express, and not on the client:
// initializing Firebase Node.js (Client)
const configFb = {
apiKey: "key",
authDomain: "xxx.firebaseapp.com",
databaseURL: "https://xxxx.firebaseio.com",
storageBucket: "xxxx.appspot.com"
};
firebase.initializeApp(configFb);
And I am also using the SDK Admin.
The problem is: Once someone logs in, this user will be the only one logged. If I open the app here, I will be logged with his account. If I sign out, this user will be signed out as well.
What I am doing wrong?
Thanks!

Node.js client SDK was not designed for this. It currently persists the session in memory. Once the user is signed in, you will have to issue your own token and return it to the client or set it in some cookie. You will then sign out that user. Future requests will check the cookie or the token you created. This is a simplistic answer as the sessions could be invalidated and you would lose that capability here. Ideally i would recommend using the client SDK on the browser or the app instead of doing it from a server.

Related

How to access firebase database from nodejs admin sdk after enforcing Firebase App Check

I have enabled Firebase App Check in my project to ensure all requests are coming only from our app. That has been working well till now (Using RecaptachaV3 as a Attestation Provider for web). However I want to access the database (rtdb) from my backend nodejs server. I'm using the firebase-admin-sdk with a service account for it. But I am unable to do it.
const { initializeApp, applicationDefault } = require('firebase-admin/app');
const { getDatabase } = require('firebase-admin/database');
const app = initializeApp({
credential: applicationDefault(),
databaseURL: '********',
});
const db = getDatabase(app);
const ref = db.ref('/some-path');
ref.once('value', (snapshot) => {
console.log(snapshot.val());
});
Below error is thrown
[2022-06-27T09:42:25.299Z] #firebase/database: FIREBASE WARNING: Missing appcheck token (https://qtalkproject.firebaseio.com/)
Isn't app check only for clients? Shouldn't firebase allow all requests that are coming from a service account? Why is it asking for an app check token? Acc to the documentation the firebase-admin-sdk is allowed to create app check tokens. If it is allowed to create app check tokens, doesn't it mean it is already authenticated? Why can't I access the database from the same admin sdk then? Am I missing something here?
If anyone else is blocked like me until firebase releases the fix, you can use the older version of the firebase admin sdk which doesn't have app check (I used v9.3.0) to access rtdb and other firebase features
Firebaser here
You are correct, the Firebase Admin SDK should bypass App Check. Thank you for finding and reporting this bug! Our team has identified the issue and currently working on a fix. We will use the following GitHub issue to track the progress https://github.com/firebase/firebase-admin-node/issues/1788

Firebase Admin SDK to Log user in from Server

I have been using Firebase Admin SDK in my Node JS code for authenticating users from the server side.
The Admin SDK provides a method admin.auth().createUser() to create new users.
admin.auth().createUser({
email,
password,
displayName: name
})
.then(function(user) {
console.log("Successfully created new user:", user.uid)
return res.send(user)
})
.catch(function(err) {
console.log("Error creating new user:", err)
return res.send(err)
})
But now how to make a user login like there is a method auth.signInWithEmailAndPassword(email, pass) in the Firebase Client SDK.
There is a method on the firebase admin SDK to get the user info by Email admin.auth().getUserByEmail(email). This method returns all the user information including password but that password is hashed. So now is there any workaround to have a proper authenticate users from Server.
My comment is a bit late but one option would be to use the Firebase REST API directly but integrated into your own server-side API for authentication. And then use a combination of that and the Admin SDK to wrap it all up. REST API docs can be found here https://firebase.google.com/docs/reference/rest/auth/#section-sign-in-email-password. You could keep your client light weight and wrap up all Firebase auth stuff, custom claims, login, logout etc. all through your own API. You would just need to use both methods to do so. This would abstract you away from any dependencies in your app and API as you could put it all in a single service provider. Just food for thought.
There is no way to log a user in with the Admin SDK. The Admin SDK runs with administrative privileges and has no need to log in.
You'll want to use one of the Firebase client-side SDKs (e.g. for Android, iOS or web users) to sign your users in to Firebase directly from the client-side code.
If you want your server-side code to know what user is signed in, you send the token from the client to your server and then decode and validate it there. See the document on verifying an ID token and the sample of server-side authentication with Cloud Functions.
Hi you can use for example in typescript the client sdk in your server side code
import firebase from "firebase/compat/app";
const firebaseConfig = {
apiKey: "",
authDomain: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: ""
};
firebase.initializeApp(firebaseConfig);
export const authSdk = firebase.auth()
// now you can do
authSdk.signInWithEmailAndPassword(userCredential.email, userCredential.password)
.then(loggedUser => {console.log(loggedUser.user?.uid)})

Firebase Admin Token is being generated with invalid signature

I have created an App using the Parse server, and have now decided to implement some aspects of firebase into my app. Im trying to accomplish this by doing the signInWithCustomToken method in swift on ios. Im calling a rest service to generate a firebase token, and then signing in with that token returned upon valid sign in on my current auth system. However, the token being generated appears to have an invalid signature when pasting it into jwt.io. The environment that im using is node based (inside the parse server). It seems very simple and i have followed the firebase instrucutions/poured over questions on this over the last few days and im really not sure what im doing wrong! Heres my rest service on how i generate the token, i initialize the server with this method:
Parse.Cloud.define("initServer", function(request, response){
var admin = require('firebase-admin');
var serviceAccount = require('/home/bitnami/apps/parse/htdocs/firebase/serviceAccountKey.json');
console.log(serviceAccount);
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: 'https://urabo-acb7a.firebaseio.com'
});
response.success("Server Init OK");
});
this is the post method i call to generate the token from firebase-admin sdk:
Parse.Cloud.define("generateFirebaseToken", function(request, response) {
var admin = require('firebase-admin');
admin.auth().createCustomToken(request.params.uid)
.then(function(customToken) {
// Send token back to client
response.success(customToken);
})
.catch(function(error) {
console.log("Error creating custom token:", error);
});
});
And of course I went into the firebase console and generated the private key, and then scp'd it over to my server. Im not really sure why this is not working, it generates a token it just doesnt appear to be valid or linked to my account. Am i missing some weird encoding issue or something with the token? Does anyone have insight on this?? Thanks so much!
—The main question is are your users signing in to the REST service through your app and then you are also trying to re-authenticate them again with the token generated in your system?
—If they will be accessing further REST functions once authenticated, then why not authenticate them successfully when 'a' token is returned?
—Usually token usage or handling is restricted by the API providers. Another option is instead of involving user auth directly with the API service, have a separate auth system — the usual SignIn process and then make API calls based on the requested API feature. That way your app is interacting with the APIs and users remain at the front end.

OAuth2 with Firebase Admin Node.js SDK and Firebase Cloud Messaging

I’m building an app that will use Firebase Admin Node.js SDK (https://github.com/firebase/firebase-admin-node and https://firebase.google.com/docs/admin/setup ) to send push notifications to mobile devices. At the moment for development purposes I’m using the service account from my own Firebase project but intend to allow users to use their own Firebase projects.
To do this, I could get the user’s project id, client email and private key, store them and use them to initialize the Admin object whenever a user wants to send an email:
admin.initializeApp({
credential: admin.credential.cert({
projectId: "<PROJECT_ID>",
clientEmail: "foo#<PROJECT_ID>.iam.gserviceaccount.com",
privateKey:"-----BEGIN PRIVATE KEY-----\n<KEY>\n-----END PRIVATE KEY-----\n"
}),
databaseURL: "https://<DATABASE_NAME>.firebaseio.com"
});
But I’d prefer not to keep this data in my db as well as make it easier for the user to authenticate my app, so I’m exploring the possibility of initializing the admin object using a Google OAuth2 refresh token:
var refreshToken; // Get refresh token from OAuth2 flow
admin.initializeApp({
credential: admin.credential.refreshToken(refreshToken),
databaseURL: 'https://<DATABASE_NAME>.firebaseio.com'
});
My question is, using this way how would I configure the credential to use a specific Firebase project (like with the projectId: "PROJECT_ID" in the admin.credential.cert method above)?
I see in the reference docs for admin.credential (https://firebase.google.com/docs/reference/admin/node/admin.credential) it says that “The refresh token credential does not grant access to every admin API.”
Is it possible to use this flow for Firebase Cloud Messaging and if not, what would be the recommended way forward?

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