Setting custom numeric key when pushing new data to firebase database - javascript

I am new to Firebase and I want to have my own keys while pushing new data to the database.
Right now I'm using the following.
uid(FirebaseAuth.getInstance().getCurrentUser().getUid())
But I want to create my own id and it must be a numeric value.
How can I create my own custom key there? Such as 0001,0002, etc.
I am asking here because I'm working on a project for online shopping. when a user adds a product to their inventory it needs to assign an id for every product. If it is not possible then just tell me no, I can accept that answer.

You can simply perform a push() function. What that would do is create a random id for your node.
databaseRef.push(); // You have created a node with a random id.
However, if you want to create a node with a numeric id you can have a function that creates a numeric value:
public static long generateRandom(int length) {
Random random = new Random();
char[] digits = new char[length];
digits[0] = (char) (random.nextInt(9) + '1');
for (int i = 1; i < length; i++) {
digits[i] = (char) (random.nextInt(10) + '0');
}
return Long.parseLong(new String(digits));
}
The function is from: 12 Digit unique random number generation in Java
You pass a length and it creates a random numeric value. The ideal length for you would be 5. Then you could go and do this:
long randomFiveDigitValue = generateRandom(5);
databaseRef.child(String.valueOf(randomFiveDigitValue)).setValue(your_object);
Another option would be to use an integer hash-code. It would decrease hash collisions, but you should be ready to handle them as with the previous function too. You could take an identifier from the order, like the date or even a mixture of factors, and do this:
//Replace all these variables with the respective value
String factors = "your_date" + "user_uid" + "product_name";
factors.hashCode(); //String date returns a integer hash value.
Here are the hashCode() collisions for 50000 randomly generated products:
COLLISIONS BETWEEN: 2 Items
ITEM 1: DATE: 24-5-2019 08:09 PM + NAME: IPHONE + UID: 4J3IF93KSKK0295[L3
ITEM 2: DATE: 24-5-2019 09:08 PM + NAME: MARKER + UID: 534KKJI903[PCO4OP5
It took a long time to generate these and I think collisions are really rare now. Like 1 to 50000 ratio. My algorithm could have been flawed, but still this way the collisions are really low.

Related

How to create an unique room ( room id ) in socket.io for two users?

I want to create an unique room id based on two users ids or emails. Those two users are going to chat with each other. I've already made login system (node+express+handlebars). When certain user enters private chat with another user I want to create a room based on their ids, so when that other user does the same procedure he will join same room because it is based on their ids. I've tried combining their ids by multiplying them. Example user1(id = 25), user2(id = 4) => roomId = 25*4 = 100. But there is a flaw if two other users with ids 20 and 5 try to chat they will have same roomId.
Convert your numeric ids to strings and zero pad them to a fixed length. Then combine the two strings together and you will have a unique name based on the two user's ids. If you want it 100% reproducible, then make sure the lower number id comes first so the two are always in the same relative order.
function createRoomName(id1, id2) {
// make sure id1 is the smaller value for
// consistency of generation
if (id1 > id2) {
// swap two values
let temp = id2;
id2 = id1;
id1 = temp;
}
return id1.toString(10).padStart(10, "0") + id2.toString(10).padStart(10, "0");
}
console.log(createRoomName(35, 19));
Or, you can just put a unique character between the two sets of digits rather than using the padding such as:
function createRoomName(id1, id2) {
// make sure id1 is the smaller value for
// consistency of generation
if (id1 > id2) {
// swap two values
let temp = id2;
id2 = id1;
id1 = temp;
}
return id1 + "|" + id2;
}
console.log(createRoomName(35, 19));
FYI, the reason for the padding or the separator character is that something like:
2,2222
and
22,222
would both generate "22222" which would conflict.
FYI, if you use the actual socket.io generated socket.id for the two users instead of your own number, then those are already unique strings of a certain length and you can directly combine them as strings to get a unique room name.

How would I check with SQL database if the random number I've generated is unique using node.js?

I have set up a web app that gives participants a random number, however, two people must not get the same number. They input their name on the website and click the okay button to get their number. All this data (name and randomly generated number that I generate with the unique random module) gets sent to MySQL database and is stored there for later use - I have to see who got which number.
The problem is, I can't find a way to check all the numbers that are in the database already to check if the newly generated number already exists before sending the new random number to the database together with the persons name.
In short, I want to check collisions with the database before inserting a new random, which has to be unique for each row, in total there can be 100 numbers (1-100). If the code catches a collision it should generate a new number and check it again for collisions.
I am basically simulating people each drawing a unique number from a hat.
Here is my JavaScript code running in node.js:
// Unique random number generator module
const uniqueRandom = require('unique-random');
// Extracts an array of objects from SQL database and transforms it into a normal array with vallues (numbers)
var sqlNumberArray = []; //this array stores all numbers from SQL database
con.query("SELECT number FROM person", function test(err, result, fields) {
if (err) {
throw err;
} else {
result.map(function(obj) {
setValue(obj.number);
});
}
});
function setValue(value) {
sqlNumberArray = value;
console.log(sqlNumberArray);
};
// Checks if the random number is unique by comparing uniqueRandom to SQL entries
var numberWasChecked = ""
let random = uniqueRandom(1, 100);
var match = false;
for (var i = 0; i < sqlNumberArray.length && !match; i++) {
if (sqlNumberArray[i] == random) {
match = true;
}
}
if (match) {
window.alert("Please reload the page and try again, there was an error assigning you a number");
console.log("Random made a duplicate number... Oops!")
} else {
app.post('/createEntry', urlencodedParser, function(req, res, ) { //This code sends data to SQL
let values = [String(req.body.name), String(random())];
console.log(String(values));
var insert = "INSERT INTO person (name, number) VALUES (?)"
con.query(insert, [values], function(err, result) {
if (err) throw err;
console.log("A new value was inserted into database. Value input: " + values);
res.render(path.join(__dirname + '/numberServe'), {
number: values[1]
});
});
});
}
If the code catches a collision with the database, it should restart the loop and get a new number. I'm new to JavaScript and coding in general, I try to grasp everything but I just don't have enough knowledge to think up solutions :(
I was trying to make it work for an entire day but I'm just out of ideas.
Selecting ahead of time to determine an existing number is subject to race conditions.
Since you want number to be unique, declare this to the database:
CREATE UNIQUE INDEX num_uniq person(number);
If you happen to get a conflict on INSERT, you'll get a duplicate key error, at which time you can pick a new number and insert.
If you are filling a 100 people with a 100 numbers, this you can use exception handling code to run a SELECT to example used numbers and eliminate these from the random number pool.

Javascript sum dynamic django rest framework entries

I'm working on an app that allows a user to calculate information regarding a trade based on their entries. I've been stuck getting proper calculations on trade sums based on entries being added after the page has already retrieved any existing entries.
<td scope="col">${sumTotal('amount')}</td>
<script>
...
mounted() {
this.trade_id = window.location.pathname.split("/")[3];
// Get entries of trade
axios
.get('/trade/' + window.location.pathname.split("/")[3] + '/entries/')
.then(response => (this.entries = response.data));
},
...
methods: {
sumTotal(base) {
return Math.round(this.entries.reduce((sum, cur) => sum + cur[base], 0));
}
</script>
When the page first loads and pulls the existing entries the first calculation (first column) is correct with 16. However, when I add a new entry the auto-calculated value is no longer true.
The first column should be 26 but now is 1610
I can add much more info as needed. I wasn't sure how much would be required and I didn't want to clutter the question.
This happened on JS side,
it is because you are adding a numeric value with a string value, the result will be the concatenation of both values in a new string.
if you noticed
previous sum was 16, and the new value is 10
their concatenation will be 1610
the solution is as simple as converting the new value from string to a numeric value
You should change the line inside sumTotal to:
return Math.round(this.entries.reduce((sum, cur) => sum + parseInt(cur[base]), 0));

Javascript equivalent of VBS redim preserve

I'm trying to rewrite some old VBScript as Javascript for an ASP.NET application and there is one line I'm not sure how to translate, and I'm not even entirely positive what it's doing.
The application essentially allows the user to enter in a new employee number to add to the database and then assign it user permissions. Don't ask me why the code is such a mess, I didn't write it originally, I'm just trying to make it work in Chrome
here's the relevant code that i've managed to translate so far:
if(form1.txtEmpno.value != ""){
var oOption;
oOption = document.createElement("OPTION");
oOption.text=form1.txtEmpno.value;
oOption.value=form1.txtEmpno.value;
form1.lstActive.add (oOption);
oOption = document.createElement("OPTION");
oOption.text="";
oOption.value="";
form1.lstPerms.add (oOption);
redim preserve arrUsers(1,ubound(arrUsers,2)+1);
arrUsers(0,ubound(arrUsers,2)) = form1.txtEmpno.value;
arrUsers(1,ubound(arrUsers,2)) = "";
form1.txtEmpno.value = "";
oOption = null;
}
here's the line in question:
redim preserve arrUsers(1,ubound(arrUsers,2)+1);
MSDN defines ReDim [Preserve] varname(subscripts) as:
The ReDim statement is used to size or resize a dynamic array that has already been formally declared using a Private, Public, or Dim statement with empty parentheses (without dimension subscripts). You can use the ReDim statement repeatedly to change the number of elements and dimensions in an array.
If you use the Preserve keyword, you can resize only the last array dimension, and you can't change the number of dimensions at all. For example, if your array has only one dimension, you can resize that dimension because it is the last and only dimension. However, if your array has two or more dimensions, you can change the size of only the last dimension and still preserve the contents of the array.
Arrays in JavaScript have different semantics to VBScript's arrays, especially in that they're actually closer to a vector than a true array, furthermore JavaScript does not provide for true N-dimensional arrays: instead you use staggered-arrays (arrays-within-arrays). Which means your VBScript cannot be syntactically converted to JavaScript.
Here's your relevant code in VBScript:
ReDim Preserve arrUsers(1,ubound(arrUsers,2)+1)
arrUsers(0,ubound(arrUsers,2)) = form1.txtEmpno.value
arrUsers(1,ubound(arrUsers,2)) = ""
We see that arrUsers is a 2-dimensional array. This will need to be converted into a staggered array, but you haven't posted the code that defines and initializes arrUsers, nor how it is used later on, so I can only work from making assumptions.
It looks to be adding 1 element to the last dimension, but the code only seems to use the extra space in the [1] subscript (i.e. it only wants the extra dimensional space for certain values of the 0th dimension instead of all values), which makes this simpler as you don't need to iterate over every 0th-dimension subscript.
JavaScript arrays have numerous function-properties that we'll use, in particular push: which appends an element to the end of an array (internally growing the buffer if necessary), and pop which removes the last (highest-indexed) element from an array (if an array is empty, it's a NOOP):
var arrUsers = [ [], [] ]; // empty, staggered 2-dimensional array
...
arrUsers[0].push( form1.txtEmpno.value );
arrUsers[1].pop();
Much simpler.
However, if this array is just part of some internal model to store and represent data then you should take advantage of JavaScript object-prototypes instead of using array indexes, as that makes the code self-describing, for example:
var User = function(empNo, name) {
this.employeeNumber = empNo;
this.name = name;
};
var users = [];
users.push( new User(1, "user 1") );
users.push( new User(23, "user 23") );
...
for(var i = 0; i < users.length; i++ ) {
alert( users[i].name );
}

Array equal two different values and change a variable dynamically

I want a user to key in an ID Number. When the user clicks on a button, the code will look for an array that has a list of all the id numbers to check if it exists. It will then go to check the price of that id number. Based on the price and what ID number was looked up I want this to change a variable called 'cost' dynamically. So for example, a user keys in the number "5555" The code looks up if the ID 5555 exists, if it does, it checks the price of that id. Based on that price, I want it to change a variable called cost. Likewise, if I looked up an id of "1234". It would look up the id, if it existed, got the price and then changed the variable called cost.
I don't even know where to begin with this. I was thinking about using arrays to map the id numbers and price but I don't know if that will work. I want a number to equal another number essentially and then change a variable based on the second number and I can't think of how to do that.
id[0] = new Array(2)
id[1] = "5555";
id[2] = "6789";
price = new Array(2)
price[0] = 45;
price[1] = 18;
You could use an object as a dictionary like object.
// Default val for cost
var cost = -1;
// Create your dictionary (key/value pairs)
// "key": value (e.g. The key "5555" maps to the value '45')
var list = {
"5555": 45,
"6789": 18
};
// jQuery click event wiring (not relevant to the question)
$("#yourButton").click(function() {
// Get the value of the input field with the id 'yourInput' (this is done with jQuery)
var input = $("#yourInput").val();
// If the list has a key that matches what the user typed,
// set `cost` to its value, otherwise, set it to negative one.
// This is shorthand syntax. See below for its equivalent
cost = list[input] || -1;
// Above is equivalent to
/*
if (list[input])
cost = list[input];
else
cost = -1;
*/
// Log the value of cost to the console
console.log(cost);
});

Categories