Firebase orderByChild and equalTo() queries don't work - android

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.

Related

Android : How to write Firebase realtime database query?

{
"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) {
}
});

Getting JsonArray from FireBase

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.

Why does my child with space does not work in firebase?

My database is this ->
{
"140107": {
"Guest First Name": "As",
"Guest Last Name": "Rodrigues",
"Email": "aaa#yahoo.com.br",
"Country": "Brazil",
"Check-In date": "11-Jun-2016",
"Check-Out date": "12-Jun-2016",
"Room": "Cama Casal com suite",
"Unit No": 1,
"Subtotal": 90,
"Revenue": 90,
"Currency": "BRL",
"Create Date": "19-May-2016"
}
}
My code is this
public void ProcuraReservaporemail(){
String email = FirebaseAuth.getInstance().getCurrentUser().getEmail();
myRef = database.getReference("reserva/");
myRef.orderByChild("Email").equalTo(email).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Reserva reserva1;
for(DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
// reserva1 = new Reserva(childSnapshot);
String Unit = (String) childSnapshot.child("Unit No").getValue();
textview2.setText(Unit);
textview2.setText( childSnapshot.child("Unit No").getValue(String.class));
}
}
The instruction childSnapshot.child("Unit No").getValue(String.class) generates an error because my bank with this space.I would have to change that so that this error does not happen anymore? I thought about changing all my bank more and more work.Do not have a specific error for the Activity stopped working.
Try using:
(String) childSnapshot.child("Unit No").getValue()
or
String.valueOf(childSnapshot.child("Unit No").getValue())

Firebase: Query to exclude data based on a condition

I'm able to get the data for a particular value in the child using orderByChild and equalTo (cool that it works for nested child as well)
private void getData() {
try {
final DatabaseReference database = FirebaseDatabase.getInstance().getReference();
database.child(Constants.TABLE_TASKS).orderByChild("user/id")
.equalTo("somevalue")
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Timber.d(dataSnapshot.toString());
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
} catch (Exception ex) {
ex.printStackTrace();
}
}
Is there an easy way to get the data where a particular value is not found, basically something like a notEqualTo("somevalue") ?
In the Firebase Query model you can not filter for inequality to a value.
But you can test for the absence of any value (essentially: the absence of a property). For example with this data model:
{
child1: {
"user": {
"id": 1,
"name": "puf"
}
},
child2: {
"user": {
"id": 2,
"name": "abe"
}
},
child3: {
"user": {
"id": 3
}
}
}
I can query for children without a user/name property with:
ref.orderByChild('user/name').equalTo(null)
Which leads to the only child that doesn't have a name:
child3
Feel free to play with my jsbin to see if you get further: http://jsbin.com/liyibo/edit?js,console
Update: I knew I'd answered this before, but couldn't find it earlier. Here's the dupe: is it possible query data that are not equal to the specified condition?. It looks like I have a mistake in there, since clearly I'm testing for the absence of a property in the above code.
I think I've found the solution and this is more of how the database should be designed and actually now I understood the intention behind Firebase guideline
https://firebase.google.com/docs/database/android/structure-data
Original Design:
{
child1: {
"user": {
"id": "id1",
"name": "puf"
}
},
child2: {
"user": {
"id": "id2",
"name": "abe"
}
},
child3: {
"user": {
"id": "id1"
"name": "puf"
}
}
}
Updated Design:
So apart from the storing the id and name of the user, we should also store a node with the id itself as the key and mark it to true
{
child1: {
"user": {
"id": "id1",
"name": "puf"
"id1": true
}
},
child2: {
"user": {
"id": "id2",
"name": "abe"
"id2": true
}
},
child3: {
"user": {
"id": "id1"
"name": "puf"
"id1": true
}
}
}
With the updated design, if i execute ref.orderByChild('user/id1').equalTo(true)
I would get output as Child1 and Child 3
and if i execute ref.orderByChild('user/id1').equalTo(null),
I would get Child2 as the output

How to query in data set of Firebase?

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());
}
};

Categories

Resources