My data structure looks like:
{
"node_1" : {
"node_2": [
{
"id": 1,
"catCode": 1,
"catName": "cat name",
"title": "Title 1",
"description": "description 1"
},
{
"id": 2,
"catCode": 2,
"catName": "cat name",
"title": "Title 2",
"description": "description 2"
},
{
"id": 3,
"catCode": 2,
"catName": "cat name",
"title": "Title 3",
"description": "description 3"
}
]
}
}
How can I query in it in a way that I only get list of titles? something like: ["Title 1","Title 2","Title 3"]
How can I query in it in a way that I get list of titles that their "catCode": 2? something like: ["Title 2","Title 3"]
The Firebase Database always returns complete nodes. So there is no single read operation that returns just the title nodes from under node_2.
That means that there is also no query that can return just the titles for items with catCode == 2. But you can get the entire nodes and then print just the titles with:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("node_1/node_2");
Query items = ref.orderByChild("catCode").equalTo(2);
items.addValueEventListener(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot itemSnapshot: dataSnapshot.getChildren()) {
Log.i(TAG, itemSnapshot.child("title").getValue(String.class));
}
}
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "loadPost:onCancelled", databaseError.toException());
}
};
Related
{
"City" : {
"New York" : {
"City Name" : "New York",
"Place to visit" : {
"Times Square" : {
"Address" : "Somewhere",
"Name" : "Times Square"
},
"Central Park" : {
"Address" : "On America",
"Name" : "Central Park"
}
}
},
"Los Angeles" : {
"City Name" : "Los Angeles",
"Place to visit" : {
"Hollywood" : {
"Address" : "Up There",
"Name" : "Hollywood"
},
"Beach" : {
"Address" : "By the sea",
"Name" : "Beach"
}
}
}
}
}
Hi, I'm a little bit new to NoSQL database especially Firebase. If I structured my data like this, how can I get the name of "place to visit" where "City name" is New York?
And I want the result (Times Square and Central Park) to be shown as ListView. How can I achieve that?
Or is there any better way to restructure my data so I can query my desired output easier?
First of all city should hold a list of items (in your case city name "New York or Los Angeles").
By this it will be easier for you to traverse through the list and fetch desired city as required in a fastest and efficient manner, this is because you will get inbuilt methods to traverse.
I have also restructured your json response in order to make it a list of objects and removed redundant variables
Below is the response
{
"City": [{
"New York": {
"Place to visit": {
"Times Square": {
"Address": "Somewhere",
"Name": "Times Square"
},
"Central Park": {
"Address": "On America",
"Name": "Central Park"
}
}
}
},
{
"Los Angeles": {
"Place to visit": {
"Hollywood": {
"Address": "Up There",
"Name": "Hollywood"
},
"Beach": {
"Address": "By the sea",
"Name": "Beach"
}
}
}
}
]
}
Because the name of the city which you want to use in your query is already a node in your Firebase database, to get those names, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference placeToVisitRef = rootRef.child("City").child("New York").child("Place to visit");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String placeToVisit = ds.getKey();
Log.d("TAG", placeToVisit);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
placeToVisitRef.addListenerForSingleValueEvent(eventListener);
Your output will be:
Times Square
Central Park
Try this one,
DatabaseReference ref= FirebaseDatabase.getInstance().getReference();
DatabaseReference refPlace= rootRef.child("City").child("New York").child("Place to visit");
refPlace.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Iterator<DataSnapshot> dataSnapshotsChat = dataSnapshot.child("articleTags").getChildren().iterator();
while (dataSnapshotsChat.hasNext()) {
DataSnapshot dataSnapshotChild = dataSnapshotsChat.next();
// check dataSnapshotChild, here you will get the details under Place to visit
Object name = ds.child("Times Square").getValue(Object.class);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
I have this JSON structure on my FireBase Database:
{
"companies": [{
"name": "Soft",
"position": "Developer",
"location": "NY",
"start": 1462060800,
"end": 1470009600,
"description" : ""},
{
"name": "Xpert",
"position": "Developer",
"location": "London",
"start": 1456790400,
"end": 1462060800,
"description" : ""},
{
"name": "AXinformation",
"position": "Developer",
"location": "Paris",
"start": 1388534400,
"end": 1456790400,
"description" : " "},
.....
.....
.....
I am trying to get that data doing something like on my code
public void onCallingFireBaseExperience() {
final FirebaseDatabase database = FirebaseDatabase.getInstance();
final DatabaseReference myRef = database.getReference("companies");
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot1: dataSnapshot.getChildren()){
Log.d(Constans.LOG, dataSnapshot1.child("name").getValue().toString())
}
}
#Override
public void onCancelled(DatabaseError error) {
Log.d(Constans.LOG, "Failed to read value.", error.toException());
}
});
}
But I am always facing a memory location on my LogCat
.google.firebase.database.DataSnapshot$1#f264efd
What I am doing wrong? How I can iterate the data?
It is because Firebase doesn't support storing arrays natively,
Firebase has no native support for arrays. If you store an array, it
really gets stored as an "object" with integers as the key names.
Please check this link from the official Firebase blog to get more information on why arrays are not supported and how you should properly structure your data to make up for it.
So, basically the way you have structured your data is not correct according to Firebase, because of which dataSnapshot.getChildren() doesn't give you any children at all.
I made a Firebase Realtime Database and integrated it with my Android app. However, I am not able to filter results based on a field.
This is my database:
{
"news": {
"15211": {
"cat_id": 3,
"cat_name": "ലോകം",
"description": "ഒരുപക്ഷെ ജിഹാദികൾ പാകിസ്താന്റെ ഭരണം അട്ടിമറിച്ചു ...",
"id": 15211,
"image": "http://d3il9y9grvji6c.cloudfront.net/57ee50db0321d.jpg",
"item_type": 1,
"time": "1475236130",
"title": " പാക്കിസ്ഥാന്റെ ന്യൂക്ലിയർ ചാവേറുകൾ ഇന്ത്യയെ ആക്രമിക്കുമോയെന്ന് ഹിലറിക്ക് പേടി",
"url": "http://www.manoramaonline.com/news/just-in/hillary-clinton-fears-nuclear-suicide-bombers-from-pakistan.html",
"url_text": "മനോരമ"
},
"15382": {
"cat_id": 4,
"cat_name": "കായികം",
"description": "ന്യൂസിലന്ഡിനെതിരായ രണ്ടാം ക്രിക്കറ്റ് ടെസ്റ്റില് ...",
"id": 15382,
"image": "http://d3il9y9grvji6c.cloudfront.net/57f0fda3abe93.jpg",
"item_type": 1,
"time": "1475411410",
"title": "ഈഡനില് ഇന്ത്യ വിജയം മണക്കുന്നു; ലീഡ് 339 ",
"url": "http://www.reporterlive.com/2016/10/02/302271.html",
"url_text": "റിപ്പോർട്ടർ"
}
}
}
The code I am using to get all items with cat_id = 3 is
DatabaseReference ref = database.getReference("news");
final Query queryRef = ref.orderByChild("cat_id").equalTo(3).limitToLast(10);
queryRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
...
}
...
}
However, this always returns no result. What could be the issue?
curl -X PUT -d '{ "1": { "name": "Hauptbahnhof Berlin", "city": "Berlin"}, "2": { "name": "Hackerscher Markt", "city": "Berlin"}, "3": { "name": "Hauptbahnhof Frankfurt", "city": "Frankfurt"} }' 'https://xxx.firebaseio.com/stations.json'
results in
which looks exported like:
{
"stations" : [ null, {
"city" : "Berlin",
"name" : "Hauptbahnhof Berlin"
}, {
"city" : "Berlin",
"name" : "Hackerscher Markt"
}, {
"city" : "Frankfurt",
"name" : "Hauptbahnhof Frankfurt"
} ]
}
Selecting the data has a null value now, why so?
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference stationsRef = database.getReference("stations");
stationsRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
ArrayList<Map<String, String>> value = (ArrayList<Map<String, String>>) dataSnapshot.getValue();
Log.d(TAG, "Value is: " + value.toString());
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w(TAG, "Failed to read value.", error.toException());
}
});
=> Value is: [null, {name=Hauptbahnhof Berlin, city=Berlin}, {name=Hackerscher Markt, city=Berlin}, {name=Hauptbahnhof Frankfurt,
city=Frankfurt}]
Firebase automatically adds index 0 as a null value, if not passed. So changing the insert to
curl -X PUT -d '{ "0": { "name": "Hauptbahnhof Berlin", "city": "Berlin"}, "1": { "name": "Hackerscher Markt", "city": "Berlin"}, "2": { "name": "Hauptbahnhof Frankfurt", "city": "Frankfurt"} }' 'https://xxx.firebaseio.com/stations.json'
fixes the problem.
I'm developing an Android app with the following Firebase database table:
"posts": {
"id_1": {
"author": "google:111527135678918251124",
"color": -2960686,
"creationTime": 1427104145195,
"text": "my text",
"title": "my Title",
"type": 0,
"visible": true
},
"id_2": {
"author": "google:111527135678918251524",
"color": -2960686,
"creationTime": 1427104145195,
"text": "my text",
"title": "my Title",
"type": 2,
"visible": true
},
"id_3": {
"author": "google:111527135678918251124",
"color": -2960686,
"creationTime": 1427104145195,
"text": "my text",
"title": "my Title",
"type": 1,
"visible": true
}
}
I'd like to be able to retrieve a the posts sorted by a child (sorted by type as an example) and be able to retrieve all the posts with a specific child value (type = 1).
Reading the Firebase docs it seems I have to write the following code, but I don't get the wanted result.
Order by type
rootRef.child("posts").orderByChild("type")
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
result = (HashMap<String, Post>) dataSnapshot.getValue();
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
I get: an unordered Map of Posts
Type = value
rootRef.child("posts").orderByChild("type").equalTo(1, "type").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
result = dataSnapshot.getValue();
result = result;
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
})
I get: null.
My Datasnapshot object has key = "posts" and value = null
About the ordering, I think the problem is that I'm retrieving data as a HashMap which is itself unordered.
As suggested in the comments the second case needs .equalTo(1) instead of .equalTo("type",1) because it's preceded by the .orderBy() method.