I use the following code to add new data to firebase.
var postData = {
NSN: NSN,
ProductName: ProductName,
AssociatedContractNumber: AssociatedContractNumber,
ItemQuantity: ItemQuantity,
viewable_by: uid,
};
InventoryID = firebase.database().ref().child('Posts').push().key;
var updates = {};
updates['/Businesses/' + uid + '/Inventory/' + InventoryID] = postData;
what i want to do is to create a list of NSNs in child "NSN" without the uniquely generated post ids. But all the attempt to add just the NSN to child NSN keeps replace the old with the new NSN. so instead of something like 10 different NSNs i only got 1 which is the most recent one added.
I used this code initially
var postNSN = {
NSN: NSN,
};
updates['/Businesses/' + uid + '/National_Stock_Numbers/' + NSN] = postNSN;
the above only replaces the existing number with the new one instead of adding the new one
I also tried this
var NSNref = database.ref('/Businesses/' + uid + '/NSNs/')
NSNref.set({
NSN: NSN,
})
but nothing happens. How can I add a new NSN to child NSNs without the uniquely generated keys?
Just use push()
Say if you had and NSN object like
var NSN = { ... }
firebase.database().ref().child('Posts').push(NSN);
Doing this will always push the item to the end of your NSN array and firebase will take care creating unique key at the time of pushing.
Remember firebase don't know about arrays it only knows about objects.
I was having some trouble when trying to retrieve from firebase. Here is my firebase structure:
What I tried to do is firstly, I wanted to get list of receiptItemID in the first picture. Then, after I get the IDs, for each ID, I wanted to get its quantity and type. After that, I will store them into array and perform some sorting.
Here is my code:
var query = firebase.database().ref('');
query.once( 'value', data => {
data.forEach(subtypeSnapshot => {
var itemKey = subtypeSnapshot.key;
var query = firebase.database().ref('').child(itemKey);
});
});
});
I managed to get the itemKey. However, when I tried to get the details of each receiptItem by the console.log that part, it prints out undefined for both. Any ideas on how to retrieve the data?
You don't need the forEach cycle, it's one level too deep. Instead, use the 'data' argument directly. This new callback should work:
var itemDetail = data.val();
var subtype = itemDetail.type;
var quantity = itemDetail.quantity;
console.log(subtype + ' ' + quantity);
In the first iteration of the forEach of your sample code, itemDetail will be equal to "Farmland" instead of the whole object; thus, subtype and quantity are null. In the new callback, itemDetail will be equal to the whole object, so subtype and quantity can be successfully declared.
var query = firebase.database().ref('receiptItems').child(itemKey);
query.once( 'value', data => {
var itemDetail = data.val();
var subtype = data.type;
// you may try data.toJSON().type as well
var quantity = data.quantity;
// try data.toJSON().quantity
console.log(subtype + ' ' + quantity);
});
In second retrieval you already have access to receiptItems/itemKey .This is a particular entry in receiptItems , not the whole receiptItems array.
So no need to apply data.forEach() once more as there is only one record. We apply data.forEach() to fetch an array of records/object. In your case it is just one entry.
Using Parse
I have an array of pointers, and I would like to remove an object from that array using only its objectId:
var rawProductObject = Parse.Object.extend("Product");
var product = new rawProductObject();
product.id = productObjectId;
userInventoryQuery = new Parse.Query("Inventory");
userInventoryQuery.equalTo("objectId", userInventory.id);
product.remove("owners", inventoryQuery)
However this does not work. I am not entirely sure about passing a query to the remove method, and not sure how to test it.
Any ideas?
We're building a site with ExpressionEngine. We are running a SQL query to gather up all member IDs for a specific member group. After that, we are using EE tags to get data from a custom member field for each member ID.
The ID and field data need to stay paired, as we will be populating a drop-down so that the ID is the value and the field data is the text, so we are currently putting them into a JS array as key/value pairs. The call is as follows:
var array= [
{exp:query sql="SELECT * FROM exp_members WHERE group_id = 5"}
{exp:member:custom_profile_data
member_id="{member_id}"}
{if company != ''}
{{member_id}:"{company}"},
{/if}
{/exp:member:custom_profile_data}
{/exp:query}
};
This gives us the output:
var array = [
{1:"name01"},
{2:"name02"},
{3:"name01"},
{4:"name03"}
];
Now, our problem. We need to remove objects based on duplicate field data (values) only, so the above array would look like this:
var array = [
{1:"name01"},
{2:"name02"},
{4:"name03"}
];
None of these IDs (keys) will ever be the same, but the field data (values) can be. So we want to keep the first KV pair that comes through with a unique value, but remove any subsequent dupes of that value - despite the fact that they will not be true "duplicate values" due to a different ID (key).
Keeping in mind that the KV pairs are all dynamic, is there any possible way to do this via JS so we can create a new array for the cleaned data to pass to the drop-down?
You could handle the duplications by modifying your MySQL query. (In my example, my custom field ID was 1.)
var myArray = [];
{exp:query sql="SELECT MIN(m.member_id) AS co_member_id, d.m_field_id_1 AS company FROM exp_members m INNER JOIN exp_member_data d ON m.member_id = d.member_id WHERE d.m_field_id_1 != '' AND m.group_id > 0 GROUP BY d.m_field_id_1;"}
myArray.push({{co_member_id}: "{company}"});
{/exp:query}
This query would use the first (in the ordinal sense) member_id found; you could also change the MIN to MAX and get the last.
This will give you a clean output in your source, without the need for any additional JS processing. I'd also recommend changing the names of the variables you're outputting as to not conflict in EE's parsing.
I would do it like...
function removeDups(arry){
var tmp = {}, retainIdx=[], newArry=[];
arry.forEach(function(obj, idx){
var val = obj[Object.keys(obj)[0]];
if(val && !tmp[val]){
retainIdx.push(idx);
tmp[val] = true;
}
});
retainIdx.forEach(function(i){
newArry.push(arry[i]);
});
return newArry;
};
I'm attempting to add/remove entries from a Firebase database. I want to list them in a table to be added/modified/removed (front end) but I need a way to uniquely identify each entry in order to modify/remove. Firebase adds a unique identifier by default when using push(), but I didn't see anything referencing how to select this unique identifier in the API documentation. Can this even be done? Should I be using set() instead so I'm creating the unique ID?
I've put this quick example together using their tutorial:
<div id='messagesDiv'></div>
<input type='text' class="td-field" id='nameInput' placeholder='Name'>
<input type='text' class="td-field" id='messageInput' placeholder='Message'>
<input type='text' class="td-field" id='categoryInput' placeholder='Category'>
<input type='text' class="td-field" id='enabledInput' placeholder='Enabled'>
<input type='text' class="td-field" id='approvedInput' placeholder='Approved'>
<input type='Button' class="td-field" id='Submit' Value="Revove" onclick="msgRef.remove()">
<script>
var myDataRef = new Firebase('https://unique.firebase.com/');
$('.td-field').keypress(function (e) {
if (e.keyCode == 13) {
var name = $('#nameInput').val();
var text = $('#messageInput').val();
var category = $('#categoryInput').val();
var enabled = $('#enabledInput').val();
var approved = $('#approvedInput').val();
myDataRef.push({name: name, text: text, category: category, enabled: enabled, approved: approved });
$('#messageInput').val('');
}
});
myDataRef.on('child_added', function(snapshot) {
var message = snapshot.val();
displayChatMessage(message.name, message.text, message.category, message.enabled, message.approved);
});
function displayChatMessage(name, text, category, enabled, approved, ) {
$('<div/>').text(text).prepend($('<em/>').text(name+' : '+category +' : '+enabled +' : '+approved+ ' : ' )).appendTo($('#messagesDiv'));
$('#messagesDiv')[0].scrollTop = $('#messagesDiv')[0].scrollHeight;
};
</script>
Now lets assume I have three rows of data:
fred : 1 : 1 : 1 : test message 1
fred : 1 : 1 : 1 : test message 2
fred : 1 : 1 : 1 : test message 3
How do I go about uniquely identifying row 2?
in the Firebase Database they look like this:
-DatabaseName
-IuxeSuSiNy6xiahCXa0
approved: "1"
category: "1"
enabled: "1"
name: "Fred"
text: "test message 1"
-IuxeTjwWOhV0lyEP5hf
approved: "1"
category: "1"
enabled: "1"
name: "Fred"
text: "test message 2"
-IuxeUWgBMTH4Xk9QADM
approved: "1"
category: "1"
enabled: "1"
name: "Fred"
text: "test message 3"
To anybody finding this question & using Firebase 3+, the way you get auto generated object unique ids after push is by using the key property (not method) on the promise snapshot:
firebase
.ref('item')
.push({...})
.then((snap) => {
const key = snap.key
})
Read more about it in the Firebase docs.
As a side note, those that consider generating their own unique ID should think twice about it. It may have security and performance implications. If you're not sure about it, use Firebase's ID. It contains a timestamp and has some neat security features out of the box.
More about it here:
The unique key generated by push() are ordered by the current time, so the resulting list of items will be chronologically sorted. The keys are also designed to be unguessable (they contain 72 random bits of entropy).
To get the "name" of any snapshot (in this case, the ID created by push()) just call name() like this:
var name = snapshot.name();
If you want to get the name that has been auto-generated by push(), you can just call name() on the returned reference, like so:
var newRef = myDataRef.push(...);
var newID = newRef.name();
NOTE:
snapshot.name() has been deprecated. See other answers.
snapshot.name() has been deprecated. use key instead. The key property on any DataSnapshot (except for one which represents the root of a Firebase) will return the key name of the location that generated it. In your example:
myDataRef.on('child_added', function(snapshot) {
var message = snapshot.val();
var id = snapshot.key;
displayChatMessage(message.name, message.text, message.category, message.enabled, message.approved);
});
To get uniqueID after push() you must use this variant:
// Generate a reference to a new location and add some data using push()
var newPostRef = postsRef.push();
// Get the unique key generated by push()
var postId = newPostRef.key;
You generate a new Ref when you push() and using .key of this ref you can get uniqueID.
As #Rima pointed out, key() is the most straightforward way of getting the ID firebase assigned to your push().
If, however, you wish to cut-out the middle-man, Firebase released a gist with their ID generation code. It's simply a function of the current time, which is how they guarantee uniqueness, even w/o communicating w/ the server.
With that, you can use generateId(obj) and set(obj) to replicate the functionality of push()
Here's the ID function:
/**
* Fancy ID generator that creates 20-character string identifiers with the following properties:
*
* 1. They're based on timestamp so that they sort *after* any existing ids.
* 2. They contain 72-bits of random data after the timestamp so that IDs won't collide with other clients' IDs.
* 3. They sort *lexicographically* (so the timestamp is converted to characters that will sort properly).
* 4. They're monotonically increasing. Even if you generate more than one in the same timestamp, the
* latter ones will sort after the former ones. We do this by using the previous random bits
* but "incrementing" them by 1 (only in the case of a timestamp collision).
*/
generatePushID = (function() {
// Modeled after base64 web-safe chars, but ordered by ASCII.
var PUSH_CHARS = '-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz';
// Timestamp of last push, used to prevent local collisions if you push twice in one ms.
var lastPushTime = 0;
// We generate 72-bits of randomness which get turned into 12 characters and appended to the
// timestamp to prevent collisions with other clients. We store the last characters we
// generated because in the event of a collision, we'll use those same characters except
// "incremented" by one.
var lastRandChars = [];
return function() {
var now = new Date().getTime();
var duplicateTime = (now === lastPushTime);
lastPushTime = now;
var timeStampChars = new Array(8);
for (var i = 7; i >= 0; i--) {
timeStampChars[i] = PUSH_CHARS.charAt(now % 64);
// NOTE: Can't use << here because javascript will convert to int and lose the upper bits.
now = Math.floor(now / 64);
}
if (now !== 0) throw new Error('We should have converted the entire timestamp.');
var id = timeStampChars.join('');
if (!duplicateTime) {
for (i = 0; i < 12; i++) {
lastRandChars[i] = Math.floor(Math.random() * 64);
}
} else {
// If the timestamp hasn't changed since last push, use the same random number, except incremented by 1.
for (i = 11; i >= 0 && lastRandChars[i] === 63; i--) {
lastRandChars[i] = 0;
}
lastRandChars[i]++;
}
for (i = 0; i < 12; i++) {
id += PUSH_CHARS.charAt(lastRandChars[i]);
}
if(id.length != 20) throw new Error('Length should be 20.');
return id;
};
})();
You can update record adding the ObjectID using a promise returned by .then() after the .push() with snapshot.key:
const ref = Firebase.database().ref(`/posts`);
ref.push({ title, categories, content, timestamp})
.then((snapshot) => {
ref.child(snapshot.key).update({"id": snapshot.key})
});
If you want to get the unique key generated by the firebase push() method while or after writing to the database without the need to make another call, here's how you do it:
var reference = firebaseDatabase.ref('your/reference').push()
var uniqueKey = reference.key
reference.set("helllooooo")
.then(() => {
console.log(uniqueKey)
// this uniqueKey will be the same key that was just add/saved to your database
// can check your local console and your database, you will see the same key in both firebase and your local console
})
.catch(err =>
console.log(err)
});
The push() method has a key property which provides the key that was just generated which you can use before, after, or while you write to the database.
Use push() to get a new reference and key to get the the unique id of the it.
var ref = FirebaseDatabase.instance.ref();
var newRef = ref.push(); // Get new key
print(newRef.key); // This is the new key i.e IqpDfbI8f7EXABCma1t
newRef.set({"Demo": "Data"}) // Will be set under the above key
How i did it like:
FirebaseDatabase mFirebaseDatabase = FirebaseDatabase.getInstance();
DatabaseReference ref = mFirebaseDatabase.getReference().child("users").child(uid);
String key = ref.push().getKey(); // this will fetch unique key in advance
ref.child(key).setValue(classObject);
Now you can retain key for further use..