I'm trying to check if a value named 'status' is equal to 'verkoper'.
But in this case it stills returns null, or what i wrote in my code "it does not works , even when it says 'verkoper' in the database.
Picture of the database structure
While the database rules are set like this
In my sign up, I push the name of the ref key equal as the uid like this, so I can easily check every user:
const uid = firebase.auth().currentUser.uid;
firebase.database().ref().child('accounts').child(uid).set({
So after that done, I try to check if the currentuser's status is equal to "verkoper"
let user_id = firebase.auth().currentUser.uid;
console.log(user_id);
const ref = firebase.database().ref(`accounts/${user_id}`);
ref.orderByChild('status').equalTo('verkoper').once('value').then((userSnapshot) => {
if (userSnapshot.exists()) {
//allow user perform action
console.log('it works');
}else {
console.log('it does not work');
// do not allow
}
}).catch((error) => {
console.error(error);
});
I hope this was enough information to figure out what the problem might be
Related
So I'm making a bot for discord but I'm having some issues with Mongoose. So what I want is basically, the user sends a message to save a Document with some of his info, but if there is already a Document with his info it will stop the process with return. So I tried this:
function main(message){
// So first user sends a message to store some data about him
let author = message.author //this is discord.js syntax, basically it returns the author of a message
let id = author.id //also discord.js syntax, returns the id from the user, in this case the author variable above
let check = logUser.findOne({userId : [id]}).exec().then(res => {
if (res) return true;
else return false;
})} // So if there is a Document with the id of the author of the message it will return true, else it returns false
if (check === true) return console.log("This User has already a Document with his info saved");
//so if the user has already a Document with his info it will return and stop the action of saving his Data
//everything from this point is basic Mongoose Syntax, to make a Document with User data
const theUser = new logUser({
_id : mongoose.Types.ObjectId(),
userName : author.username,
userId : author.id,
currency : 0
})
theUser.save()
.then(result => console.log(result))
.catch(err => console.log(err))
console.log(`User ${author.username} was stored into the database!`)
}
It fails in the if statement that checks if the user has a Document with his info already. I've tried multiple things but it doesn't work.
I think that the solution for this problem has to do with async functions but I'm not sure, and I don't know that much about async processes.
Thanks in advance!
The problem is that your treating logUser.findOne as synchronous. Perform the check in findOne callback like so:
function main(message){
// So first user sends a message to store some data about him
let author = message.author //this is discord.js syntax, basically it returns the author of a message
let id = author.id //also discord.js syntax, returns the id from the user, in this case the author variable above
logUser.findOne({userId : [id]}).exec().then(res => {
let check = Boolean(res);
if (check === true)
return console.log("This User has already a Document with his info saved");
const theUser = new logUser({
_id : mongoose.Types.ObjectId(),
userName : author.username,
userId : author.id,
currency : 0
});
theUser.save()
.then(result => {
console.log(result);
console.log(`User ${author.username} was stored into the database!`)
})
.catch(err => console.log(err))
});
}
Are you purposely wrapping the id in an array? I don't know your schema but it seems odd and may contributing to your issues. userId : [id]
You may want to consider async/await to reduce callbacks. You can also look into using a unique index to avoid multiple requests in the future. Using a unique index will throw an error when trying to save the same document twice.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await
https://docs.mongodb.com/manual/core/index-unique/
I am trying to update the user account details in firebase but I have noticed that the input value for one of my fields keeps coming up as undefined even when I console.log it. I am working in two files one is a loginjs file in which I am defining the user input.
signUpForm.addEventListener('click', function (e) {
e.preventDefault();
isSigningUp = true;
var email = signUpEmailInput.value;
var password = signUpPasswordInput.value;
var displayNameUser = displayNameInput.value;
var userPrivateKey = signUpPrivateKey.value;
var user = firebase.auth().currentUser;
var photoURL = "https://www.gravatar.com/avatar/" + md5(email);
if (signUpPasswordInput.value !== signUpPasswordConfirmInput.value) {
setSignUpError('Passwords do not match!');
} else if (!displayNameUser) {
setSignUpError("Display Name is required!");
} else if (!userPrivateKey) {
setSignUpError('You need to set a Private Key!');
} else {
auth.createUserWithEmailAndPassword(email, password)
.then(function (user) {
user.updateProfile({
displayName: displayNameUser,
photoURL: photoURL,
privateKey: userPrivateKey
}).then(function () {
// Update successful.
window.location.href = 'chat.html';
}).catch(function (error) {
// An error happened.
window.alert("Some unexpected error happened!");
});
user.sendEmailVerification().then(function () {
// Email sent.
}).catch(function (error) {
// An error happened.
window.alert("Email was not able to send!");
});
})
.catch(function (error) {
// Display error messages
setSignUpError(error.message);
});
}});
The weird thing is that the user input for my displayname and photoURL are working just fine, but when it comes to my private key user input it registers the input when it goes to the chat page and I do a console.log(user.privatekey) It says it is undefined.
In my chatjs file, thats when I am pushing the all the user profile information. The chatjs file basically allows a user to send a message, the message and all the user profile information gets stored onto the firebase database.
messages.push({
displayName: displayName,
userId: userId,
pic: userPic,
text: myString.toString(),
privatekey: user.privatekey,
timestamp: new Date().getTime() // unix timestamp in milliseconds
})
.then(function () {
messageStuff.value = "";
})
.catch(function (error) {
windows.alert("Your message was not sent!");
messageStuff;
});
The thing again is that the privatekey does not get stored at all, which is what I am not understanding, since it is registering user input in the loginjs file but when I go to the chatjs file it keeps saying the value is undefiend. I have googled everywhere and I still haven't found a solution to it. Any help would be greatly appricated!
It's because the Firebase user object you receive from Firebase is not customizable. When you call the createUserWithEmailAndPassword(email, password) method, it returns a specifically defined user object back to you - check out the docs for the properties of this object.
The properties displayName and photoURL both work because they are already properties of the user returned. privateKey is not an existing property of the Firebase user object, and Firebase doesn't know how to handle an update call for a property that isn't defined. Check out this question & answer where Frank explains that Users in Firebase aren't customizable - you need to store any extra info separately.
As you can see below i'm trying to read a list of data from the database and then loop over the result, in javascript. The function runs whenever i open/refresh the page:
firebase.database().ref("Users/" + uid + "/rooms").on("value", function(snapshot) {
snapshot.forEach(function(e) {
var element = e.val();
var roomId = element.Id;
});
});
However, that string concatenation to specify the User Id doesn't work for some reason. When i replace it with the user Id directly like this:
firebase.database().ref("Users/GR3JFsMrKOjCrLhDNFMaq72COd07/rooms").on.....
that works fine. But of course i want to use the variable which contains the Id of the current user.
The uid variable is assigned a value in the onAuthStateChanged when checking if the user is signed in:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
uid = user.uid;
If I add a console.log like this:
firebase.database().ref("Users/" + uid + "/rooms").on("value", function(snapshot) {
console.log(snapshot.parent);
snapshot.forEach(function(e) {
the output with the first code example (using uid variable) is: undefined.
If i specify the User Id directly it is: room-id-1 (the result i want).
How do i make the string concatenation work? Or is this the wrong way of specifying the path of the current user?
It is extremely unlikely that the problem is in the string concatenation itself. It is much more likely that uid simple doesn't have a value yet when you start reading from the database.
To make sure the uid is available, put the reading of the data into the auth state listener like this:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
uid = user.uid;
console.log("uid="+uid);
firebase.database().ref("Users/" + uid + "/rooms").on("value", function(snapshot) {
snapshot.forEach(function(e) {
var element = e.val();
var roomId = element.Id;
console.log("roodId="+roomId);
});
});
}
})
I'm trying to get the user name, but the output is undefined. I still new to javascript on firebase.
firebase.auth().onAuthStateChanged(function (user) {
if (user) {
document.getElementById('welcome').innerHTML = 'Welcome! '+ user.name;
window.user = user;
alert( user.email);
// User is signed in.
}
you may want to use the displayName property instead of name. Have a look at the documentation to see which properties the user object provides.
I have a firebase database and I am currently trying to use cloud functions to perform an operation when a value in my database changes. So far, it successfully triggers code to run when the value in my database changes. However, when the database value changes, I now need to check another value to determine it's status, and then perform an action after that. The problem is that I have ~0 experience with JS and I have no way of debugging my code other than deploying, changing the value in my database, and looking at the console log.
Is there any way to look up another value in the database and read it? How about look up a value and then set a value for it? Here is the code:
exports.determineCompletion =
functions.database.ref('/Jobs/{pushId}/client_job_complete')
.onWrite(event => {
const status = event.data.val();
const other = functions.database.ref('/Jobs/' + event.params.pushId + '/other_job_complete');
console.log('Status', status, other);
if(status == true && **other.getValueSomehow** == true) {
return **setAnotherValue**;
}
});
This code partially works, it successfully gets the value associated with client_job_complete and stores it in status. But how do I get the other value?
Additionally, if anyone has any JS or firebase documentation that they think would help me, please share! I have read a bunch on firebase here : https://firebase.google.com/docs/functions/database-events but it only talks about events and is very brief
Thank you for your help!
When writing a database trigger function, the event contains two properties that are references to the location of the data that changed:
event.data.ref
event.data.adminRef
ref is limited to the permissions of the user who triggered the function. adminRef has full access to the database.
Each of those Reference objects has a root property which gives you a reference to the root of your database. You can use that reference to build a path to a reference in another part of your database, and read it with the once() method.
You can also use the Firebase admin SDK.
There are lots of code samples that you should probably look at as well.
I'm maybe a bit late, but I hope my solution can help some people:
exports.processJob = functions.database.ref('/Jobs/{pushId}/client_job_complete').onWrite(event => {
const status = event.data.val();
return admin.database().ref('Jobs/' + event.params.pushId + '/other_job_complete').once('value').then((snap) => {
const other = snap.val();
console.log('Status', status, other);
/** do something with your data here, for example increase its value by 5 */
other = (other + 5);
/** when finished with processing your data, return the value to the {{ admin.database().ref(); }} request */
return snap.ref.set(other).catch((error) => {
return console.error(error);
});
});
});
But take notice of your firebase database rules.
If no user should have access to write Jobs/pushId/other_job_complete, except Your cloud function admin, You need to initialize Your cloud function admin with a recognizable, unique uid.
For example:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const adminCredentials = require('path/to/admin/credentials.json');
admin.initializeApp({
credential: admin.credential.cert(adminCredentials),
databaseURL: "https://your-database-url-com",
databaseAuthVariableOverride: {
uid: 'super-special-unique-firebase-admin-uid'
}
});
Then Your firebase database rule should look something like this:
"client_job_complete": {
".read": "auth !== null",
".write": "auth.uid === 'super-special-unique-firebase-admin-uid'"
}
Hope it helps!
You have to wait on the promise from a once() on the new ref, something like:
exports.processJob = functions.database.ref('/Jobs/{pushId}/client_job_complete')
.onWrite(event => {
const status = event.data.val();
const ref = event.data.adminRef.root.child('Jobs/'+event.params.pushId+'/other_job_complete');
ref.once('value').then(function(snap){
const other = snap.val();
console.log('Status', status, other);
if(status && other) {
return other;
}
});
});
Edit to fix the error that #Doug Stevenson noticed (I did say "something like")