"locs" : {
"-Lci8jGrXCEP-r6LBxD8" : {
"title" : "Marriage"
},
"-Lci9UNW80J2Jap_UHwj" : {
"title" : "Visit"
}
},
My firebase realtime database looks like this. I want to add three other values under this same push key namely latitude and longitude and address.
mDatabase.child("users").child(mUserId).child("locs").push().child("title").setValue(text.getText().toString());
This works in first activity. In second activity I retrieve lat and long and save it in a string lat and long respectively. Now I want these two values and addr to be saved under this same key.
This is my expected result
"locs" : {
"-Lci8jGrXCEP-r6LBxD8" : {
"title" : "Marriage"
"lat" : "xxx.xxxxxx"
"long" : "xxx.xxxxxx"
"addr" : "Street 112 xxxx"
},
"-Lci9UNW80J2Jap_UHwj" : {
"title" : "Visit"
"lat" : "xxx.xxxxxx"
"long" : "xxx.xxxxxx"
"addr" : "Street 1212 Flat 6"
}
},
You'll need to do two things:
Make sure the second activity knows the key to update. You can do this either by passing the key along from the first activity to the next (in an intent or in shared preferences), or by looking it up in the second activity based on some other unique property that you know the value of.
Update the location for that key, instead of generating a new one. You do this by calling update() instead of set() and using child(key) instead of push(). So:
Map<String, Object> values = new HashMap<String, Object>();
values.put("title", "new updated title");
values.put("newprop", "value of new prop");
mDatabase.child("users").child(mUserId).child("locs").child(key).updateChildren(values);
Related
I have a content node that I retrieve from a Firebase Realtime Database.
I utilize .orderByChild("time") to get a Data Snapshot of the first 5 blog objects ordered by their earliest timestamps. I
am currently attempting to utilize .indexOn : "time" instead so that I do not have to utilize .orderByChild("time") as I am expecting for the blog objects to already be ordered by their timestamp by back-end when they are retrieved. (I am going to be working with a very large number of blog objects, so I want to utilize .indexOn : "time" in back-end instead of orderByChild("time") in front-end to increase efficiency). Currently, .indexOn does not work and the data isn't ordered by their time fields when it is retrieved.
query without .indexOn
// this works fine
// startAt is utilized for saving last blog object retrieved to retrieve more data
query =
FirebaseDatabase.getInstance().getReference()
.child("content")
.orderByChild("time")
.startAt(nodeId)
.limitToFirst(5);
query with .indexOn
// this along with the Firebase rules below does not return the same result as above
// startAt is utilized for saving last blog object retrieved to retrieve more data
query =
FirebaseDatabase.getInstance().getReference()
.child("content")
.startAt(nodeId)
.limitToFirst(5);
Firebase rules:
{
"rules": {
".read": true,
".write": true,
"content" : {
".indexOn": "time"
}
}
}
JSON structure of data in Firebase :
"content" : {
"blog-0001" : {
"content_id" : "blog-0001",
"image" : "someimage",
"time" : 13,
"title" : "title1",
"type" : "blog"
},
"blog-0002" : {
"content_id" : "blog-0002",
"image" : "someimage",
"time" : 12,
"title" : "title2",
"type" : "blog"
},
"blog-0003" : {
"content_id" : "blog-0003",
"image" : "someimage",
"time" : 11,
"title" : "title3",
"type" : "blog"
},
"blog-0004" : {
"content_id" : "blog-0004",
"image" : "someimage",
"time" : 15,
"title" : "title4",
"type" : "blog"
}
...
}
You seem to be misunderstanding what .indexOn does, and how it related to orderByChild("time").
To retrieve child nodes from content ordered by (and possibly also filtered on) time, you will always need to call orderByChild("time").
If you define an index (using ".indexOn": "time") that ordering and filtering will be done on the server.
Without an index, all data under content will be downloaded to the client, and the ordering/filtering will be performed client side.
So .indexOn is not a replacement for orderByChild. Instead the two work hand in hand to perform efficient ordering and filtering of data.
This question already has an answer here:
Firebase sort by points depending on date
(1 answer)
Closed 4 years ago.
I have a database that looks like this:
{
firstitem : {
"name" : "first_item_name",
"date" : "29/11/2018",
"user" : "random user",
"url" : "My Url",
"tag" : "firstitem"
},
seconditem : {
"name" : "second_item_name",
"date" : "20/11/2018"
"user" : "another user",
"url" : "a url",
"tag" : "seconditem"
},
thirditem : {
"name" : "third_item_name",
"date" : "20/11/2017"
"user" : "another user",
"url" : "a url",
"tag" : "thirditem"
}
ect....
}
I want to be able to have an option to sort by date, starting at the newest, and descending to the oldest. How can I achieve this?
This is my method for calling the firebase strings at the moment:
if (dataSnapshot.exists()) {
Log.i("Event", "Added");
Firebase_Strings dlStrings = dataSnapshot.getValue(Firebase_Strings.class);
p9p_strings.DOCUMENTARY_NAME.add(dlStrings.name);
p9p_strings.DOCUMENTARY_SYNOPSIS.add(dlStrings.about);
p9p_strings.DOCUMENTARY_URL.add(dlStrings.url);
p9p_strings.DOCUMENTARY_UPLOADED.add(dlStrings.date);
p9p_strings.DOCUMENTARY_TAG.add(dlStrings.tag);
There is no way in which you can sort your items by date if you are storing the date as String "29/11/2018" and not as a timestamp.
To solve this, you should change the type of your date property to number.
And here you can how to add and get back the timestamp.
Using Morphia, is it possible to perform a saveOrUpdate / upsert operation on an object embedded inside an array.
Consider the following document :
{
_id : "abcd",
myArray : [{
"key" : "areaTotal",
"value" : "101.9",
"label" : "Total area (municipality)"
}, {
"key" : "areaUrban",
"value" : "803",
"label" : "Total area (urban)"
}, {
"key" : "populationDensity",
"value" : "15991",
"label" : "Population desnsity"
}
]
}
Is there a clean way to replace for example array element with key "areaUrban" by another object
such as
{
"key" : "areaUrban",
"value" : "123",
"label" : "a new label"
}
For now I do it in two update operations first delete, then add :
UpdateOperations<T> ops = createUpdateOperations().removeAll("myArray ", new BasicDBObject("key", "areaUrban"));
update(createQuery().field("_id").equal(myObjId),ops);
UpdateOperations<T> ops2 = createUpdateOperations().add("myArray ", myReplacementObject);
update(createQuery().field("_id").equal(myObjId),ops2);
Which works fine but can I do it in only one update op (either with morphia or with plain mongo java driver) ?
Also if a matching object did not originally exist in the array, then the myReplacementObject object should just be added to the array.
thanks
With the $ positional operator:
db.test.update({_id: "abcd", "myArray.key": "areaUrban"}, {$set: {"myArray.$.value": 123, "myArray.$.label": "a new label"}})
[Edit] As JohnnyHK mentions in the comments this won't upsert the nested document if it doesn't exist.
I'm trying to fetch records within a specific radius in km/miles.
mongodb 2d index:
db.collection.ensureIndex({locaction:"2d"})
a record in the collection has the indexed key:
"location" : { "longitude" : 34.791592164168, "latitude" : 32.0516908 0405 }
Calling collection's getIndexes() from shell gives me this:
...{
"v" : 1,
"key" : {
"location" : "2d"
},
"ns" : "events.events",
"name" : "location_2d"
}...
despite all the above, trying to fetch records with this command fails:
> db.events.find({location:{ $near :{ longitude:34,latitude:32},$maxDistance:10 / 3963.192}})
anyone can point out what prevent this from working?
AFAIK, $near takes an array of the two target values, so you can try giving your values in array: -
db.events.find({location:{ $near : [34, 32],$maxDistance:10 / 3963.192}})
I pass out a ajax get which contains a parameter i.e. date added to db.
Java queries the DB for results of persons added on this date, and builds a JSON object for me like so:
{
"resultdata" : { "rowsReturned" : "2", "fetchTime" : "180"}
"row_1" : { "name" : "Larry", "sex" : "m", "age" : "26", "location" : "seattle" }
"row_2" : { "name" : "Pedro", "sex" : "m", "age" : "22", "location" : "unknown" }
}
I can then return the JSON object as a String. I'd then like to dynamically build a table based on these results.
First of all is the JSON object correct for building a table?
The result data tells me how many rows and the time taken in milliseconds, followed by however many rows in that particular format.
I then want to create a table inside a specific div element once these results are returned to my browser on the fly with no page refreshes etc.
so Id expect Table headers with titles of each column - followed by you guessed it 2 rows.
How is the best way to go about doing this. I am familiar with jQuery, JSON is totally new to me and dealing with JSON in jQuery is something i'm keen on learning.
Any help is much appreciated.
you can use jsonlint to validate your json.
Yours is not valid. It's missing some ',':
{
"resultdata" : {
"rowsReturned" : "2",
"fetchTime" : "180"
}, // <--
"row_1" : {
"name" : "Larry",
"sex" : "m",
"age" : "26",
"location" : "seattle"
}, // <--
"row_2" : {
"name" : "Pedro",
"sex" : "m",
"age" : "22",
"location" : "unknown"
}
}
I've made a little DEMO of one possible way how to loop through the json with for-in-loops
for (key in json) {
loops through the json and stores each key in the 'key' variable.
in your case 'resultdata','row_1','row_2'.
So to access the data for each key you write json[key] which translates to json['row_1'] for example.
Now you do the same thing for the row_1 object with:
for(key1 in json[key])
key1 are now the keys in the row_1 object: 'name','sex',...
to access the data now you'll write json[key][key1] which would be json['row_1']['name'] for example.
of course it's advisable to give the keys meaningful names to avoid confusion like in my example:)
Your JSON looks fine for building a table.
You'll want to use $.getJSON() to fetch the JSON data, as it will automatically parse the JSON into an object for you. If you need the advanced features of $.ajax(), you can call $.parseJSON() on the returned data from the AJAX call and it will parse the JSON into an object.