I was trying to fetch all the (records)entries of a firebase database and put them on a table in HTMl.
I tried doing it like this -
function Fetch_data_from_database(to_database,table_id) //function that fetches all the data from the database passed
{
firebase.database().ref(to_database).once('value',function(snapshot){
snapshot.forEach(
function(ChildSnapshot){
let name = ChildSnapshot.val().Name;
let Password = ChildSnapshot.val().Password;
let User_ID = ChildSnapshot.val().User_ID;
console.log("gonna print " + name + " " + Password + " " + User_ID );
add_to_table(table_id,name,Password,User_ID);
}
);
});
}
I created a function which intends to read all the (records)entries from a firebase folder , but I am stuck at an error [at line firebase.database().ref ] saying -
I am new to firebase , can anyone please tell me what is wrong ? , also is there any easy way to do it?
Since you are using V9 as described in your comment above, you will want to call getDatabase() instead of firebase.database().
Related
Click here for picture Overview of the classes/entities
Hi guys, It could be great if someone could re-code and help me on this.I am new in D365 and JS. Basically, how can I query the parent to case_adjustment from adjustment invoice record using JS. I have provide my current code, please help me to review it. I have try everything but so far no luck. Sorry for my unprofessional picture. But I hope you understand it and could help me to code for this situation.
I have try to enable the debugger and it shows that the code cant run the adjustmentTypeLookup. and thats why it cant pass the value to retrieveRecord .Thank you.
function adjustmentInvoiceApproveAmount(executionContext) {
try {
// Get the form context
const formContext = executionContext.getFormContext();
// Extract attribute values from the form
const adjustmentAmount = formContext.getAttribute("case_adjustmentamount").getValue();
const amountDue = formContext.getAttribute("case_amountdue").getValue();
const adjustmentTypeLookup = formContext.getAttribute("case_adjustmenttype").getValue();
// Exit as adjustmenttype is not set
if (!adjustmentTypeLookup) return;
// Extract the adjustment type record ID from the payment type lookup
const adjustmentTypeId = adjustmentTypeLookup[0].id.substring(1, 37);
//console.log("GUID \"case_adjustmenttype\" = " + adjustmentTypeId + " ; " + typeof adjustmentTypeId);
//console.log(adjustmentTypeId);
// Retrieve a SINGLE case_adjustmenttype based on lookup ID on form
Xrm.WebApi.retrieveRecord("case_adjustmenttype", adjustmentTypeId, "$select=case_name").then(
function success(adjustmentType)
{
// If the payment type is credit notes then check payment amount and resit amount
if (adjustmentType.case_name.toLowerCase() == "Credit notes".toLowerCase())
{
if (adjustmentAmount >= amountDue) {
formContext.getEventArgs().preventDefault();
Xrm.Navigation.openErrorDialog({message:"Payment Amount cannot be more than Resit Amount."})
}
}
//Otherwise do nothing
},
function (error)
{
console.log(error.message);
}
);
}
catch (error)
{
console.log(error);
}
}
If you are struggling with the code of retrieving data using web API, I would suggest checking out "CRM REST Builder".
https://github.com/jlattimer/CRMRESTBuilder
Import the solution and refresh the solutions page in dynamics which will show up the button to start this tool. This tool is awesome at generating code for different scenarios.
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) { });
}
EDIT: The following was not my true issue. See answer.
I'm working on a simple html/javascript chat client using Google firebase. The following code is intended to be a rudimentary system of registering and logging in users, wherein the function is provided with an array ($usr) containing a username and password at the 1 and 2 positions.
The local username and password $usr[1-2] are then checked against the database's result (getuser variable, structured as user obj) to determine whether or not a username has already been taken or if the user's credentials are valid. Please note that this is a personal project, the data is not intended to be sensitive.
//Registers user credentials with input [cmd, user, pass]
var auth = function ($usr) {
var db = firebase.database().ref('chatapp/users/' + $usr[1]);
var getuser;
user = {'name': $usr[1], 'pass': $usr[2]};
db.once('value').then(function(snapshot) {
getuser = snapshot.val();
if ($usr[0] === "/register") {
if (getuser.name !== $usr[1]) {
db.set(user);
notify('Registered ' + $usr[1] + ' with pass "' + $usr[2] + '"');
} else {
notify('Username "' + $usr[1] + '" already taken, try again');
}
} else if ($usr[0] === "/login") {
if (getuser.name !== $usr[1] || getuser.pass !== $usr[2]) {
notify('Invalid credentials ' + $usr[1] + ':' + $usr[2]);
} else {
notify($usr[1] + ' logged in');
}
}
});
};
The issue comes into play at db.once(). The data is being retrieved but is delayed. If a user is attempting to register (getuser.name !== $usr1) will always return True because the variable is set to undefined. However, the login command works flawlessly because by then getuser has been set to the value retrieved from Firebase.
I have tried using .once() only to set the variable, or as a function returning snapshot.val(). I have tried including all of my code within the callback for .once() and using snapshot.val()[name] and [pass] rather than storing it to a variable. The only solution to this seems to be a manual break in the program flow.
In addition, I've also found that using getuser[name] does not work in instances where getuser.name does work, which makes no sense and further infuriates me. Please help, it's 2:12am here.
Here is the official documentation.
Here is a relevant Stackoverflow question, which may be the solution I'm looking for but I don't understand it.
What really confounds me is that the function following .then is supposedly reliant on the data being confirmed, which obviously isn't the case.
This is the code that worked for me:
//Registers user credentials with input [cmd, user, pass]
var auth = function ($usr) {
var db = firebase.database().ref('chatapp/users/' + $usr[1]);
var getuser;
user = {'name': $usr[1], 'pass': $usr[2]};
db.once('value').then(function(snapshot) {
getuser = snapshot.val();
if ($usr[0] === "/register") {
if (getuser === null) {
db.set(user);
notify('Registered ' + $usr[1] + ' with pass "' + $usr[2] + '"');
} else {
notify('Username "' + $usr[1] + '" already taken, try again');
}
} else if ($usr[0] === "/login") {
if (getuser.name !== $usr[1] || getuser.pass !== $usr[2]) {
notify('Invalid credentials ' + $usr[1] + ':' + $usr[2]);
} else {
notify($usr[1] + ' logged in');
}
}
});
};
The question was not actually my issue. What led me to believing that retrieval of the data was being delayed is that my code had initially been outside of the .once() method's callback function. If you use .once()'s callback function to write snapshot.val() to a variable, and then write the rest of your code outside of the callback function, the data is written asynchronously and your variable will be set to undefined until the true value can be retrieved from the server. I believe that a workaround for this is calling a function with the parameter snapshot.val() from within the callback, or simply writing your code within the callback (above).
The actual issue with my code was with the line if (getuser.name !== $usr[1]). This causes an error if the value of getuser is null. The fixed code is above.
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'));
}
I need to read a value in a firebase database at a certain time. Additionally i'd prefer to NOT have the read value updated even if the dataBases voteValue changes at some time later. Though if its easier i guess i'd go with it.
I have a number of time slots in my firebase database - they happen to be time in seconds. I have called these timeSlots and I have a vote value at each of these timeSlots.
so in the example below, say the time is # 11seconds. i want to read that the vote for that timeSlot has a value of 8
Currently i have:
var ref = new Firebase ('https://aB8ppi-f0h02.firebaseio.com/web/data');
function myFunction (x) {
ct = player.getCurrentTime()
timeSlot = Math.round(ct)
var voteData = ref.child("vid1");
voteData.orderByValue().equalTo(timeSlot).on("value", function(dataSnapshot) {
var Yval = dataSnapshot.vote + x;
};
//then update the dBase to the new value
voteData.child("slot" + timeSlot).set({
slot: timeSlot,
vote: Yval
});
};
Firebase seems well setup for onChange events etc, but i don't need that here. Note: i do NOT want the client to have to login / auth.
Can you suggest how i can retrieve, change and set a new value to a firebase database? Thanks much.
Alright worked it out. What i found was that i needed to clean up BOTH the writing to the dBase and the reading from it too. I hope this helps someone else one day :)
The writing function is now
ref.child("vid1/slot"+timeSlot+"/vote").on("value",function(snapshot){
slotVal = (snapshot.val());
}, function (errorObject) {
console.log("the read failed: " + errorObject.code);
});
ref.child("vid1/slot"+timeSlot).set({
vote: slotVal + x
});
and the reading function:
ref.child("vid1/slot"+timeSlot+"/vote").on("value",function(snapshot){
//console.log(snapshot.val());
slotVal = (snapshot.val());
}, function (errorObject) {
console.log("the read failed: " + errorObject.code);
slotVal = 0; // better than returning null, eh?
});
return (slotVal);