Retrieve all registered users in firebase - node.js

I am using firebase database in nodejs.
I simply want to fetch all the users that exists in my firebase database.
Currently I am trying this but it is only return one single user:
var config = {
apiKey: "AIzaSyBmgbfgdhs4efg9gFo",
authDomain: "my-test-app.firebaseapp.com",
databaseURL: "https://my-test-app-default-rtdb.firebaseio.com",
projectId: "my-test-app",
storageBucket: "my-die-app.appspot.com",
messagingSenderId: "534345345",
appId: "1:534345345:web:cceb16e6vvdd456",
measurementId: "G-YDZ8Y87GETR",
};
firebase.initializeApp(config);
var ref = firebase.database().ref("users");
ref.once("value", function (snapshot) {
snapshot.forEach((child) => {
console.log(child)
});
});
In firebase users I can only see this single user aswell, but infact I have more users there:
{
"XG0hYDjhekjdfJX5zLmfUFPQBifkmZA3": [
"XG0hYDjhekjdfJX5zLmfUFPQBifkmZA3",
"user1#gmail.com",
"835457568",
"Michael James ",
"user1#gmail.com"
]
}
And this is the only user I am getting in code aswell.
I am not the owner of this database, may be thats the reason?
Is there any specific way to retrieve all users list?

I believe the question answers itself
In firebase users I can only see this single user
If there is only only user node in the /users node as shown in your question
users {
"XG0hYDjhekjdfJX5zLmfUFPQBifkmZA3": [
"XG0hYDjhekjdfJX5zLmfUFPQBifkmZA3",
"user1#gmail.com",
"835457568",
"Michael James ",
"user1#gmail.com"
]
}
that means only one node exists - therefore only one node can be retrieved.
The confusion may be that while Firebase has users that can authenticate, those users are stored in the Firebase back-end server only. It doesn't necessarily mean other user data was written to the /users node.
In other words, if the app code does not specifically write data to /users, it won't exist.
Check your authentication code and see if it writes data to /users at some point - if not, there's your problem.
If that's the issue, which I suspect it is, you can't retrieve a list of Firebase users from the SDK directly, but you can using Firebase Admin coupled with Cloud Functions.
Here's an example: Get All Users
Alternatively (and my suggested path), you can also add code to the app so when users authenticate, if their users node doesn't exist within /users, create it (using the users uid returned from the Auth parameter as the node key)

What user are you logged in as? Is that the user you can see? What are your Firebase security rules like?
If you have reasonably secure rules setup, that would be the reason users can only see their own nodes.
See these docs: https://firebase.google.com/docs/database/security#section-authorization

Related

How to verify a user is authenticated and present in firebase, when doing read/write operations on the rest-api, in nodejs, UI is in flutter?

I have built a rest-api using Nodejs and mongodb for the flutter app, works completely fine and i am authenticating user using firebase phone authentication and I have some complex work, cannot be handled by the firebase, so setup a restapi for the work, so when user hits that api, i want to make sure that user is present and authenticated by the firebase before reading and writing from the db, on the server(api) side, written in node js. How to achieve this, any ideas?
P.S : I am open for ideas, and thanks for the help in advance :)
If anything wrong in doing this or with question, suggest for the edit
Just use the currentUser method of FirebaseAuth to verify if the user is logged in
FirebaseUser user = await FirebaseAuth.instance.currentUser();
if(user!=null){
// do your thing
}
Edit
In case you want to verify user on your server, use Firebase Admin SDK in your Nodejs server. You will have to pass some identifier like UID, email or phone number; whichever applicable.
admin.auth().getUser(uid)
.then(function(userRecord) {
// See the UserRecord reference doc for the contents of userRecord.
console.log('Successfully fetched user data:', userRecord.toJSON());
})
.catch(function(error) {
console.log('Error fetching user data:', error);
});
Reference to the docs for more details : https://firebase.google.com/docs/auth/admin/manage-users

Firebase Sending Request to Server from Client Safe Using Socket.IO?

I understand that security rules are the safest way to protect data however it doesn't support my method in storing user data when they click on specific elements. This is because if I turn write == true they are able to change the database willingly which I don't want them to do; I just want to record their input from my website privately.
Hence, my solution was to create another database on the server. Initialise the firebase realtime database on the server.js file. I thought this would be ideal, as the client doesn't access to any of the credentials (And yes I know, even if the user does have it, it's not that bad anyway but just in case).
So if I were to use socket.io to request from the client (all they see is "socket.emit('value', 'value')) then wouldn't it be safe as they are not seeing anything related to the firebase database as it is all on the server (which is not shown to the user)?
I just want clarification on if this is safe and ideal because it seems to logically work if I were to neglect the security rules.
Apologise to the previous users that replied on my previous post, this may be very similar but I have elaborated a little bit more to make what I am doing a bit more clearer.
Thanks for all your help.
Client Code:
var a = 0;
socket.emit('value', a);
Server Code:
firebase.initializeApp({
apiKey: VALUE,
authDomain: VALUE,
databaseURL: VALUE,
projectId: VALUE,
storageBucket: VALUE,
messagingSenderId: VALUE,
appId: VALUE,
measurementId: VALUE
});
socket.on('value', function(data) {
var ref = firebase.database().ref('node');
ref.set(data);
})
The code you shared indeed seems (unlike your first question) to no longer expose identity of your Firebase project to the caller. So there is no way for the caller to determine the database URL from what you shared.
Whether this is secure enough for your needs, only you can determine. But a few things to keep in mind:
If a user can find the database URL through another means, your ".read": true, ".write": true rules still allow them to both read all data, and write whatever they want.
Your code allows writing anything the user wants to the database. You'll want to lock that down either in your code, or with Firebase's server-side security rules.

How to initialize and use passport for different kinds of users?

I am not exactly sure how to ask this question, so it may seem a little absurd!
I am developing an application using Node and Express (middleware). I've also used Passport (Local) for authentication.
Regarding the business of my application, I need to manage two kinds of users.
Definition
Application users: people who use the application.
Administrators: people who manage the content of application.
Now, I used passport (Local) for authenticating the application users. Therefore, I've called my passport-setup in "app". The current setup knows the application users' table and works fine. However, for administrators there is another collection which needs to be queried. Question: How can I setup tow different collections using passport? Let me show you some code to illustrate the situation.
app.js
const port = process.env.PORT || 5000;
var passport = require('passport');
var setupPassport = require('./setup-passport');
//Some code here and then
setupPassport();
setupPassport
module.exports = function () {
passport.serializeUser(function (user, done) {
done(null, user._id);
});
passport.deserializeUser(function(id,done){
User.findById(id,function(err,user){
done(err,user);
});
});
};
//And
passport.use('login',new localStrategy(function(username,password,done){
User.findOne({userName:username},function(err,user){
if(err){
return done(err);
}
if(!user){
return done(null,false,{message:'The username has not been found!'});
}
user.checkPassword(password,function(err,isMatch){
//...
As you can see, the config has been set for application users. What if I want to set another collection for administrators? Is there any solution for setup passport for different collections ? Both users are going to use the same application concurrently, so both can login and logout.
A likely but ugly solution
I have been thinking about putting all users information in a single collection, though I am sure it is not nice!
Maybe you can add a field into a schema that takes in a boolean. Something like
admin:{
type: Boolean,
default: false
}
So if a person is registered as an admin the value will be true, otherwise, it will be false.
Every time when you are logging the users in, you can put an if statement under the User.findOne() query function to check if the admin field is set to true and therefore determine the type of users.
Furthermore, you should use the world collection in MongoDB instead of a table. It's a NoSQL DB.

Where to add Firebase in Node

I will be making a Web App in Firebase. Problem is, I am still unsure of how a few things will work.
Eventually I will need a server (which will be in Node) for sending emails and such. One of my biggest questions though is where Firebase will actually be needed. Let me elaborate some more!
I see that in the docs (here) you can add Firebase to your server by adding the following code in Node:
var firebase = require("firebase");
firebase.initializeApp({
serviceAccount: "path/to/serviceAccountCredentials.json",
databaseURL: "https://databaseName.firebaseio.com"
});
But you can also add Firebase directly to the browser with the following code:
<script src="https://www.gstatic.com/firebasejs/3.1.0/firebase.js"></script>
<script>
// Initialize Firebase
// TODO: Replace with your project's customized code snippet
var config = {
apiKey: "apiKey",
authDomain: "projectId.firebaseapp.com",
databaseURL: "https://databaseName.firebaseio.com",
storageBucket: "bucket.appspot.com",
};
firebase.initializeApp(config);
</script>
So my question is in what circumstances would I do either of the above? When would I add Firebase to the browser, and when would I add Firebase to the server? What uses do both provide?
For instance, could I access the Realtime Database from the server without connecting to Firebase? And if I add Firebase to the server, do I then have to add it again to the Browser? Please explain, thank you!
You already have most of the parts of the answer in your question.
Say that you want the users of your web app to be able to send email. As you say, you'll typically want to do that from your server, since you'd otherwise have to rely on the email client of your users.
But even when it's your node.js server that sends the email, it's the users of your web app that determine when and where to send the email. So the users needs a way to talk to your node.js script.
You can easily let the users talk directly to your node.js server. Set up some express.js endpoints and you're in business. But then you'd need to set up security on your node.js server, ensure that you can handle cases where your users are submitting more email requests than your node.js script can handle, etc. Lot of plumbing work that has nothing to do with sending an email.
Another way to handle this scenario is to let the web clients write "email requests" into the Firebase database. Simply include the Firebase client (with the snippet you have) and:
ref.child('outbox').push({
to: 'puf#stackoverflow.com',
subject: 'nice answer!',
body: '...'
})
Now your web client is done and the user can continue.
On the node.js server you include the Firebase client (with the second snippet you have) and connect to the same database, waiting for the email requests to come in:
ref.child('outbox').on('child_added', function(snapshot) {
var msg = snapshot.val();
sendEmailTo(msg.to, msg.subject, msg.body).then(function(error) {
// if the message was sent, delete it from the queue
if (!error) snapshot.ref.remove();
});
})
This approach is covered in our classic blog post on Firebase application architectures as pattern 2.

Meteor - Check if user is logged in as administrator (Client - Side)

I'm currently developing an app which needs users and administrators. What I do right now is, I create an admin account on the client with username 'admin' and a default password that should be changed over the accounts-ui.
I do this because creating a user like this:
Accounts.createUser({
username : 'admin',
email : 'test#test.com',
password : 'changethispasswordovertheuserinterface',
profile : { type : 'admin' }
});
doesn't work for me on server side. That means I just create the admin in my client.js and just use this code to check if the admin is logged in.
Template.admin.isAdmin = function () {
var currentUser = Meteor.user();
// Is this hackable?
if (null !== currentUser) {
if ('admin' === currentUser.username) {
return true;
}
}
};
Is this the best way to approach this? And most importantly, is my site hackable like this (Could somebody fake it)?
Yes this is hackable, one could pull up the chrome inspector and modify this quite easily. Or even faster, by typing something like Template.admin.isAdmin = function () { return true; } into Chrome's web console
The best approach would be to only provide the information to the client from the servers end if the user is an admin. So this would mean using Meteor.allow to ensure the database can only be changed by an administrative user, if peforming ops from the client end.
It also depends a bit on what you want to use 'isAdmin' for too. If its content, you could generate the html on the server's end and send it down to the client in a Meteor.methods. At the moment the templating system doesn't provide for locking down the UI on the clients end depending on what the user's document contains.
For any administrative commands, you could use a Meteor.call at which point the user is vetted on the server's and and the transaction is performed there.
The answer on this thread works too AND the top-voted answer has code for a server side, Meteor method call.

Resources