Is there any way to update and push simultaneously?
I want to update a key2 in my object and simultaneously push unique keys under timeline in a single request ref().child('object').update({...}).
object
key1:
key2: // update
key3:
timeline:
-LNIkVNlJDO75Bv4: // push
...
Is it even possible or one ought to make two calls in such cases?
Calling push() with no arguments will return immediately (without saving to the database), providing you with a unique Reference. This gives you the opportunity to create unique keys without accessing the database.
As an example, to obtain a unique push key, you can do some something like:
var timelineRef = firebase.database().ref('object/timeline');
var newTimelineRef = timelineRef.push();
var newTimelineKey = newTimelineRef.key;
With this, you can then perform a multi-level update which makes use of the new key:
var objectRef = firebase.database().ref('object');
var updateData = {};
updateData['object/key2'] = { key: 'value' };
updateData['object/timeline/' + newTimelineKey] = { key: 'value' };
objectRef.update(updateData, function(error) {
if (!error) {
console.log('Data updated');
}
});
Related
There are questions on how to update nested properties for a Firebase record, but no answers on how to create records with nested properties.
This and this were similar but did not help.
From the web, the goal is to create a Firebase record with nested properties.
Using dot notation works for updates, but a nested hierarchy doesn't get created when reusing the same key for creating the record.
Which makes sense because the key doesn't impart any information about the data types of the child properties.
What is the right way to create an object with nested properties?
async test(serviceId, numCredits, emailAddress) {
// Set credits key.
let creditsKey = `credits.${serviceId}.numAllowed`;
try {
// Get user matching #emailAddress.
let user = await this.getUser(emailAddress);
// New user? Create database record.
if (!user) {
this.db_
.collection('users')
.add(
{
emailAddress: emailAddress,
[{creditsKey}]: numCredits
}
);
// Nope, user exists so update his/her record.
} else {
// Set update query.
let query = this.db_
.collection('users')
.where('emailAddress', '==', emailAddress);
// Run update query.
const querySnapshot = await query.get();
return querySnapshot.docs[0].ref.update({
[creditsKey]: firebase.firestore.FieldValue.increment(numCredits)
});
}
} catch(e) {
debug('Error in test(): ' + e);
}
}
If I correctly understand your question, the following would do the trick. (There are probably more elegant solutions however...)
const obj = {};
obj.numAllowed = numCredits;
const obj1 = {};
obj1[serviceId] = obj;
// ...
this.db_.collection('users')
.add(
{
emailAddress: emailAddress,
credits: obj1
})
I would like to be able to publish simultaneously in two directories of my Firebase database. I created a function for this, according to the example proposed in the "Update specific fields" section of the Firebase Javascript documentation:
function linkTwoUsers(user1, user2) {
// The two users are "connected".
var user1Data = {
userLink: user2
};
var user2Data = {
userLink: user1
};
var updates = {};
updates["/users/" + user1] = user1Data;
updates["/users/" + user2] = user2Data;
return database
.ref()
.update(updates)
.then(() => {
return res.status(200).end();
})
.catch(error => {
return res.status(500).send("Error: " + error.message);
});
}
The problem is that when I run the function, instead of uploading the directories, it replaces all the data present in it.
Here are the user directories before the function:
And then:
How do we make sure the data doesn't overwrite the others? Thank you for your help.
Try to narrow your path to just the property you are trying to update:
updates["/users/" + user1 + "/userLink/"] = user1;
updates["/users/" + user2 + "/userLink/"] = user2;
It seems as though you're creating an entirely new object when you set:
var userData = { someThing: stuff }
When you pass that in, it will override the original object. One way you might solve this (there might be a more efficient way) is to grab the objects from Firebase, add the new property and value to the object, then send the entire object back into Firebase.
In some javascript frameworks, you should be able to use the spread operator to set all of an object's props to another object like this:
var newObject = { ...originalObject }
newObject.userData = "something"
// then save newObject to firebase
Firebase - How to get list of objects without using AngularFire
I'm using typescript, angular2 and firebase.
I'm not using angularfire. I want to extract the data using their Api
My firebase url is /profiles
This is the list of profiles I'm looking to extract:
Thanks.
Use a simple value event and re-assign the array every time the value changes.
JSBin Demo.
var ref = new Firebase('https://so-demo.firebaseio-demo.com/items');
ref.on('value', (snap) => {
// snap.val() comes back as an object with keys
// these keys need to be come "private" properties
let data = snap.val();
let dataWithKeys = Object.keys(data).map((key) => {
var obj = data[key];
obj._key = key;
return obj;
});
console.log(dataWithKeys); // This is a synchronized array
});
I'm trying to store an object in my chrome extension containing other objects using chrome.storage - but am having trouble initializing it and properly fetching it using chrome.storage.sync.get. I understand that I'm supposed to get objects in the form of chrome.storage.sync.get(key: "value", function(obj) {} - the issue is I'm not sure how to
Initialize the object the first time with get
Properly update my object with set
I have the following code to create the object and add the data I need.
allData = {};
currentData = {some: "data", goes: "here"};
allData[Object.keys(allData).length] = currentData;
This will correctly give me an object with it's first key (0) set to currentData. (Object: {0: {some: "data", goes: "here"}}) Working as intended, and allData[Object.keys(allData).length] = currentData; will properly push whatever currentData is at the time into my Object later on.
But how do I properly store this permanently in chrome.storage? chrome.storage.sync.get("allData", function(datas) {}) fails to create an empty allData variable, as does allData: {}, allData = {}, and a variety of different things that return either undefined or another error. How do I properly initialize an empty object and store it in chrome.storage? Or am I going about this all wrong and need to break it down into associative arrays in order for it to work?
I essentially need that small block of working code above to be stored permanently with chrome.storage so I can work with it as needed.
You first need to set the data inside the storage:
allData = {};
currentData = {some: "data", goes: "here"};
// to initialize the all data using the storage
chrome.storage.sync.get('allData', function(data) {
// check if data exists.
if (data) {
allData = data;
} else {
allData[Object.keys(allData).length] = currentData;
}
});
// Save it using the Chrome extension storage API.
chrome.storage.sync.set({'allData': allData}, function() {
// Notify that we saved.
message('Settings saved');
});
After that you should be able to access the data using the chrome.storage.sync.get('allData', function(){ ... }) interface.
You can easily do this with the new JavaScript (ECMAScript 6), have a look into Enhanced Object Properties:
var currentData = {some: "data", goes: "here"};
chrome.storage.local.set({allData: currentData });
In the old way, was something like this:
var obj = {};
var key = "auth";
obj[key] += "auth";
obj[key] = JSON.stringify({someKey: someValue});
I have just discovered how cool node js is and was looking at options for persisting. I saw that you could use redis-client to store data in redis and I have been able to store data ok, like so:
var redis = require('redis-client');
var r = redis.createClient();
var messege = {'name' => 'John Smith'};
var type = "Contact";
r.stream.on( 'connect', function() {
r.incr( 'id' , function( err, id ) {
r.set( type+':'+id, JSON.stringify(messege), function() {
sys.puts("Saved to redis");
});
});
});
This store a key with a json string as the value. I am however trying to retrieve all the keys from redis and loop around them. I am having trouble figuring out the way to do this, could anyone point me in the right direction?
Cheers
Eef
To get keys from redis, you should use the .keys parameter. The first parameter that you pass is a 'filter' and .keys will return any items matching the filter.
For example r.keys('*', ...) will return all of the keys in redis as an array.
Here's the documentation on this command: http://redis.io/commands/keys
To loop through them, you can just do a simple for in as follows:
r.keys('*', function (keys) {
for (key in keys) {
console.log(key);
}
});