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);
});
});
}
})
Related
I'm creating my custom order id with auto-increment generator function for my project. I will state my question here, if you want to know the whole story please read below.
As written in the title, I need a way to reject my set to Firebase and it has to be done in 1 query. Currently, it will write my orderID to Firebase without rejecting it. But I need to reject if there is the same ID in the table.
The short version of my code will be posted here, the whole function will be posted below.
firebase.database().ref('orderCounter/orderIDsChecker/'+orderID).set({
id: orderID,
}, function(error) {
if (error) {
console.log('Order ID fail to generate. Regenerating new ID')
createOrderID(orderCounterRef);
} else {
console.log('Order ID created!')
}
});
}
The story,
I'm creating my own custom order id with auto-increment generator function for my project. The problem is that if multiple users creating order at the same time, it will generate the same id. Yes, I can use transaction() to solve the problem but I have no idea how to use it. Therefore, I have created my own version of the "transaction". With my method, I am able to prevent duplicates id unless 2 or more users create order within 1 second of gap. Or if anyone is kind enough to show me an example of how to write a transaction for my function, I thank you in advance.
The flow of the code is,
Get "currentMonth" and "orderIdCounter" from Firebase -> orderIdCounter +1 and update to Firebase -> start the process of generating order id -> Send the generated id to firebase -> If return success "order ID created", If not "got duplicate id" Re-run the whole process.
Below is the code for my order id generator function.
function createOrderID(orderCounterRef){
var childData = [];
var orderID;
//Get the Current Month and Order ID Counter from Firebase
orderCounterRef.on('value', function(snap) { childData = snapshotToArrayWithoutID(snap); });
var currentMonth = childData[0];
var orderIDCounter = childData[1];
if (orderIDCounter !== undefined){
//Update orderIDCounter on Firebase.
//This is to prevent duplicate orderID when multiple users is creating order at the same time.
var IDCounter = parseInt(orderIDCounter) + 1;
//Set IDCounter to 3 digits
IDCounter = ('00' + IDCounter.toString()).slice(-3);
firebase.database().ref('orderCounter/orderIDCounter').set(IDCounter);
//Handle the process to generate Order ID. Return in YYMMxxx(auto increment) format.
orderID = handleCreateOrderID(currentMonth, (parseInt(orderIDCounter) - 1));
//Check if duplicate ID on firebase
firebase.database().ref('orderCounter/orderIDsChecker/'+orderID).set({
id: orderID,
}, function(error) {
if (error) {
console.log('Order ID fail to generate. Regenerating new ID')
createOrderID(orderCounterRef);
} else {
console.log('Order ID created!')
}
});
}
return orderID;
}
My DB:
You should indeed use a transaction as you have mentioned in your question.
The following should do the trick:
//Declare a function that increment a counter in a transaction
function createOrderID() {
var orderIdRef = firebase.database().ref('orderId');
return orderIdRef.transaction(function(currentId) {
return currentId + 1;
});
}
//Call the asynchronous createOrderID() function
createOrderID().then(function(transactionResult) {
console.log(transactionResult.snapshot.val());
});
If you want to start the counter at a specific value, just create an orderId node in your database and assign a specific value to it, e.g; 1912000.
If you just want to start at 1, you don't need to create a node, it will be automatically created with the first call to the createOrderID() function.
Thank you, #samthecodingman & #Renaud Tarnec for your advice.
I took #samthecodingman's code and change a bit to fit my project. But I use generateOrderID() only to call the result and it works well. But you won't get any value with just the code. I call out another function (connectToFirebase) whenever users enter the page. I am not sure why it works or if this is the right way, but it works for me and that's good enough.
export function generateOrderID(){
var orderId;
var childData = [];
const orderCounterRef = firebase.database().ref('orderCounter/');
//Get the Current Month from Firebase
orderCounterRef.on('value', function(snap) { childData = snapshotToArrayWithoutID(snap); });
//Check ID format YYMMXXX (XXX=auto_increment). Hanlde auto_increment for Year and Month
handleOrderIdFormat(childData[0], orderCounterRef)
//transaction
orderCounterRef.child('orderId').transaction(function(currentId) {
orderId = (currentId||0) +1;
return orderId;
}, function(err) {
if( err ) {
console.log(err)
}
});
return orderId;
}
export function connectToFirebase(){
//Connection Firebase Database
const orderCounterRef = firebase.database().ref('orderCounter/');
orderCounterRef.on('value', function(snap) { });
}
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
I want to send some generated data to the to a specific object child.
var user = firebase.auth().currentUser;
var key = user.uid;
// Set path for created user to be UID
var createProfileRef = firebase.database().ref("profiles/" + key);
var info;
createProfileRef.on("value", function(snapshot) {
var getData = snapshot.val();
info = Object.keys(getData)[0];
});
// Save Plan to logged inn user
var sendData = firebase.database().ref("profiles/" + key + "/" + info + sendDate);
savePlan(sendFat, sendProtein, sendCarbohydrate);
function savePlan(sendFat, sendProtein, sendCarbohydrate) {
var addData = sendData.push();
addData.set({
Macros_Fat: sendFat,
Macros_Protein: sendProtein,
Macros_Carbohydrate: sendCarbohydrate,
});
The only thing I need for this to work is to get the value of the variable "info". I just can't get it to get transferred outside of the function it is declared in...
If I place the function savePlan inside the snapshot it works, but it generated around 1000 keys constantly until I exit the application.
The easiest way you can do that is by setting the variable value in localStorage in the firebase function itself and get it outside the function from localStorage.
Here's the code:
// in firebase function
localStorage.setItem('info',info)
//outside the firebase function
localStorage.getItem('info');
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.
So I am doing a project right now requiring the storage of user preferences with JSON. I have searched for a decent amount of time now but can find no solution.For example sake There are three variables user, permissions, serverid . I figured this would work.
tempObject = {
user: []
};
tempObject.user.push({perm:permissions, server:serverid});
Then i would stringify and turn into a JSON. However the output came out like this:
{user[{perm:4, server:883}]}
This was my desperate attempt at grouping the perm and server variables under the indivisuals UserID so further down in the code i can fetch the permissions of each userID. But as you can see it didnt print the user variable, just changed it to an array and took user as a litteral string.
tl;dr
In short i need help being able to have a JSON file be written to where it stores the perm and serverID under the UserID.
Make user an object. Change this:
user: []
for this:
user: {}
and then set the keys like this:
user.perm = 4;
user.server = 883;
For security reasons, client-side JavaScript is not permitted to write to the disk. This sounds like you need a database.
You could leverage localStorage, or perhaps a cookie as an alternate to a database.
I think you should change the users array to an object; that way could key by userID.
for example:
var data = {
users: {}
};
const userID = 1234; // or could be a string like 'john_doe'
const userPermissions = { perm: 4, server: 883 };
// set the user's permissions
data.users[userID] = userPermissions;
// fetching user's permissions
const userData = data.users[userID];
console.log('User ' + userID +' has perm = ' + userData.perm + ' and server = ' + userData.server);
Now saving and loading of this data using local storage is easy:
function saveData() {
localStorage.setItem('UserData', JSON.stringify(data));
}
function loadData() {
data = JSON.parse(localStorage.getItem('UserData'));
}