This question already has answers here:
Query based on multiple where clauses in Firebase
(8 answers)
Closed 4 years ago.
I have firebase like this (I Can't change the table design)
{
"Visits" : {
"-LOyE4h8k218xg-SI2Hy" : {
"Enabled" : false,
"visitorLocation" : "01",
"visitorId" : "22"
},
"-LOyG4__aiiJ3FBVnWbU" : {
"Enabled" : false,
"visitorLocation" : "02",
"visitorId" : "22"
},
"-LOyG5Wyu3cZmZFaCBxY" : {
"Enabled" : false,
"visitorLocation" : "03",
"visitorId" : "22"
},
"-LOyG7gkUj8OFdEsyBGS" : {
"Enabled" : false,
"visitorLocation" : "04",
"visitorId" : "22"
}
}
}
Stored in the firebase,
I would search using visitorLocation and visitorId, and then change the Enabled value.
what i have right now:
DatabaseReference ref =
FirebaseDatabase.getInstance().getReference("visitores");
//This is good, Returns the 4 nodes.
Query q = ref.orderByChild("visitorId").equalTo("22");
q.orderByChild("visitorLocation").equalTo("01").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
dataSnapshot.getChildren().iterator().next().getKey();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
but later i get error: You can't combine multiple orderBy calls!
can anyone help ? how can i search by multiple key values ?
Thank you !!!
You can not use "visitorLocation=04 && visitorId=22 " at the same time but you can modify your table structure by combining these two fields like this "visitorLocation_visitoId=04_22"
To do so you need to add a field in your firebase database table structure so you can apply this AND query
Related
I'm developing an Android app with the following Firebase database table:
"fav" : {
"-Ktf0tmShJ48-oH76Or3" : {
"article" : {},
"articleId" : "1005",
"id" : 1505034214723,
"userId" : "xUdklm4VMFa9FJvA15XvlIkYKFA3",
"userId_articleId" : "xUdklm4VMFa9FJvA15XvlIkYKFA31005"
},
"-Ktf13BfglsB4sFhHv-P" : {
"article" : {},
"articleId" : "1001",
"id" : 1505034257363,
"userId" : "xUdklm4VMFa9FJvA15XvlIkYKFA3",
"userId_articleId" : "xUdklm4VMFa9FJvA15XvlIkYKFA31001"
}
}
I want to query by the string "userId_articleId" like this:
FirebaseDatabase.getInstance().getReference().child("fav").orderByChild("userId_articleId").equalTo(firebaseUser.getUid() + article.id)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()){
for (DataSnapshot data : dataSnapshot.getChildren()){
fav = data.getValue(Fav.class);
favKey = data.getKey();
starItem.setIcon(R.drawable.star);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.i("fyales","The dataChanged");
}
});
}
But I can't get the Object I wanted, The weirdest thing is that I can get the Object I want correctly by the key "articleId" or "id". It can also work if if I give the definite value "xUdkl" to "userId_articleId" if the "userId_articleId" in the database is the value "xUdkl" like this:
.orderByChild("xUdkl").add....
But it can't work if I give the value "xUdklm4VMFa9F" to "userId_articleId" if the "userId_articleId" in the database is "xUdklm4VMFa9F" like this.
orderByChild("xUdklm4VMFa9F").add...
I don't know why.It is related the length of String or it's just a bug in firebase ? Any help will be appreciated.
I solved the problem...The reason is that I didn't keep the data fresh . So I synced the data before I used them by ref.keepSynced(true).You can get the answer in
Enabling Offline Capabilities on Android.
Let's consider a "UserBean" with a property "emails" that is an ArrayList<EmailBean>.
When saved in Firebase it's like :
"users" : {
"$userID" : {
"emails" : [
"0" : {
"type" : "first",
"address" : "google#google.com",
"private" : true
},
"1" : {
"type" : "second",
"address" : "firebase#firebase.com",
"private" : false"
}
],
"name" : "Mitch"
}
}
So is it possible to achieve something like this :
"users" : {
"$userID" : {
"emails" : [
"first" : {
"address" : "google#google.com",
"private" : true
},
"second" : {
"address" : "firebase#firebase.com",
"private" : false
}
],
"name" : "Mitch"
}
}
I would prefer to not having to save each address one at a time.
Maybe there's an annotation to tells Firebase to use this property as a key ?
Regards.
I recomend you using the code below:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference emailsRef = rootRef.child("users").child(userId).child("emails");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String type = ds.child("type").getValue(String.class);
ds.child("type").getRef().getParent().setValue(type);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
emailsRef.addListenerForSingleValueEvent(eventListener);
What have i tried with this code? So in order to achieve what you want, first of all we got the value of your type key. Then we get a step up in the tree and set the partent with the value of your type key for each particular node.
Having the value of type in stead of 0, 1 and so on, to get the work done, just remove the type key, from each node using removeValue() method directly on the reference.
This question already has an answer here:
Firebase query if child of child contains a value
(1 answer)
Closed 6 years ago.
What is the proper way to query for every Comment (POJO) attached to a Photo (POJO) in Android. In Firebase, I have the following structure for a photo collection:
"photos" : {
"-KaeuYf9jXcy4oqpRqbi" : {f
"entities" : {
"type" : {
"image" : {
"bucket" : "bucket",
"prefix" : "https://s3-us-west-2.amazonaws.com/",
"suffix" : "image.jpg"
}
}
},
"stats" : {
"liked" : 0
},
"text" : "Person Detected!",
"timestamp" : 1484631194257
}
}
and for comments collection:
"comments" : {
"-KdE6Hwua8d6sBQimPos" : {
"attachphoto" : {
"-KaeuYf9jXcy4oqpRqbi" : true
},
"attachuser" : {
"-KaeuYHjkdf9okflslf" : true
},
"displayName" : "Gary",
"text" : "ok",
"timestamp" : 1487385995844
},
"-KdE6IPc-NL-6zGkwXq3" : {
"attachphoto" : {
"-KaeuYf9jXcy4oqpRqbi" : true
},
"attachuser" : {
"-KaeuYHjkdf9okflslf" : true
},
"displayName" : "Thomas",
"text" : "ok",
"timestamp" : 1487385997735
}
}
In Android I'm using a FirebaseAdapter, but I am having trouble defining a proper Query that would only retrieve comments attached to a specific photo. I have the key of the Photo
FirebaseListAdapter adapter = new CommentAdapter(this, Comment.class, R.layout.item_comment, QUERY){
#Override
protected void populateView(View v, Comment model, int position) {
if(model.getDisplayName()!=null) {
String[] name = model.getDisplayName().split(" ");
((TextView) v.findViewById(R.id.id)).setText(name[0]);
}
((TextView) v.findViewById(R.id.content)).setText(model.getText());
}
};
I thought I could define something like:
final FirebaseDatabase database = FirebaseDatabase.getInstance();
final DatabaseReference commentsRef = database.getReference("comments");
Query query = commentsRef.orderByChild("attachphoto").equalTo()
But I'm having some disconnect on how to finish this. First project using Firebase, so any help/tips would be much appreciated!
Firebase is rather noSQL, therefore there are limits which one has to work around... especially when designing the data-structure. for example, in this case it might make sense to add the ids of the related users & comments (or even the related comments altogether) into a nested node of the structure, which represents the photo. there are other ways to get there - while one always needs to consider how to look up the details later on (because the structure dictates which queries are possible and which not).
This question already has answers here:
How do you prevent duplicate user properties in Firebase?
(2 answers)
Closed 6 years ago.
I am adding username for my Chat App to Firebase Database successfully.
I implemented in activity:
FirebaseDatabase firedb = FirebaseDatabase.getInstance();
in createUser Method.
private void createUser(String uname){
Map<String,Object> newUser = new HashMap<String, Object>();
newUser.put("uname",uname);
DatabaseReference dbref = firedb.getReference();
dbref.child("Users").push().setValue(newUser);
}
When user click a button this method works. This method work correctly but I want to make uname primary key. I do not want to add a username if it is alerady exists.
Database Structure:
Rules:
{
"rules": {
".read": true,
".write": true
}
}
Finally, how to prevent duplicated uname ?
You have to add a top level /uname/ Node. Your data will be like this for example :
{
"Users" : {
"user1" : {
"uname" : "value1",
},
"user2" : {
"uname" : "value2",
},
"user3" : {
"uname" : "value3",
},
},
"uname" : {
"value1": "user1",
"value2": "user2",
"value3": "user3",
}
}
Now you have to Enforce New Data Structure:
{
"rules": {
"users": {
"uname": {
".validate": "!root.child('uname').child(newData.val()).exists()"
},
}
}
}
This question already has answers here:
Query based on multiple where clauses in Firebase
(8 answers)
Closed 6 years ago.
Consider following firebase structure :
{
"users" : {
"00:03:aa:dc:1c:2b" : {
"firstName" : " Ofek",
"groupName" : "thailand",
"lastName" : "Ron",
"registration" : {
"type" : "regular",
"time" : 1418288589636
},
"phoneNumber" : "345345345"
},
"04:46:65:8D:60:C6" : {
"firstName" : " Ofek",
"groupName" : "thailand",
"lastName" : "Ron",
"registration" : {
"type" : "regular",
"time" : 1418288589630
},
"phoneNumber" : "345345345"
},
}
}
how do you implement the following query :
SELECT * FROM USERS WHERE groupName="thailand" and registration.time>=1418288589631
I was trying to do it like this :
fireBase.orderByChild("groupName").startAt("thailand").endAt("thailand").orderByChild("time").startAt("1418288589631")
but that threw an exception since firebase doesnt allow multiple orderbys...
Any ideas?
Firebase currently only supports a single orderBy per query.
So if you want to filter (or order) on more than one property, you'll either have to do the additional filtering (or ordering) client-side in your JavaScript code or you'll have to come up with your own indexing scheme that combines the properties.