Reputation: 843
I am using firebase database for storing data of my iOS application.
Here is my firebase database high level structure:
In this database I am saving data of a menu item in menu tab. This is list of all menus. This is list menus where all menu item has a unique key:
There is one more node "Users" and it has one child "Consumer"
I am saving 'liked' and 'disliked' menu item in different children of "Consumer" node.
I am working on a screen where I have to show all details of menuItems which are liked by user. As you can see I am saving only menuItem keys in "Like_Deal_Dish" node.
This is my code by which I am fetching all keys which have added in "Like_Deal_Deish" child:
Database.database().reference().child("Users").child("Consumer").child((Auth.auth().currentUser?.uid)!).child("Like_Deals_Dish").observeSingleEvent(of: .value) { datasnapshot in
if datasnapshot.exists() {
print("Like Deals - \(datasnapshot)")
}
else{
print("Liked data is not available")
}
}
Console log where I am getting list of all liked ,menuItem:
What should be the query to fetch only those menuItems whose keys are added in the "Like_Deal_Dish" ?
Upvotes: 4
Views: 1936
Reputation: 1
//Create a class
public class FirebaseDataHelper { //...}
//create a interface in it with method for whatever you want to return
public interface OnDataFetchedListener{
void onDataFetched(List<User> data);
}
//Add below Methods as your concern
//This method helps you to perform mysql 'IN' operation on firebase Here my concern to get List of users store on Node NODE_USERS on firebase for given list of keys in a Syncronized way
public void fetchUserDataForSelectedKeys(List<String> keyList,OnDataFetchedListener dataFetchedListener){
List<User> data = new ArrayList<>();
FirebaseDatabase.getInstance().getReference().child(CommonConstants.NODE_USERS).get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
@Override
public void onComplete(@NonNull Task<DataSnapshot> task) {
if(task.isSuccessful()){
DataSnapshot snapshot = task.getResult();
for (String key:
keyList) {
if(snapshot.hasChild(key)){
data.add(snapshot.child(key).getValue(User.class));
}
}
dataFetchedListener.onDataFetched(data);
}
}
});
}
//This method used when using concept of pk in andorid and you can modify it according to your requirement //I stored ids of users in node NODE_FREINDS under current userID and i want to get complete user for each id stored in that node(Actual user info stored in NODE_USER) and return list when completely fetched
public void fetchUserDataForPath(String path,OnDataFetchedListener dataFetchedListener){
List<User> data = new ArrayList<>();
String[] children = path.split("/");
DatabaseReference fromReference = FirebaseDatabase.getInstance().getReference();
for (String child:
children) {
fromReference=fromReference.child(child);
}
DatabaseReference finalFromReference = fromReference;
FirebaseDatabase.getInstance().getReference()
.child(CommonConstant.NODE_USER)
.get()
.addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
@Override
public void onComplete(@NonNull Task<DataSnapshot> task) {
if(task.isSuccessful()){
DataSnapshot snapshot = task.getResult();
finalFromReference.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
@Override
public void onComplete(@NonNull Task<DataSnapshot> task) {
if(task.isSuccessful()){
DataSnapshot snapshot1 = task.getResult();
for (DataSnapshot sn:
snapshot1.getChildren()) {
data.add(snapshot
.child(Objects.requireNonNull(sn.getKey()))
.getValue(User.class));
}
dataFetchedListener.onDataFetched(data);
}
}
});
}
}
});
}
}
Upvotes: 0
Reputation: 16446
You fetched menu id from Like deals. so now you can use that value to query again the menus
child
Here is example (not tested on xcode so forgive me for syntax error if any)
Database.database().reference().child("Users").child("Consumer")
.child((Auth.auth().currentUser?.uid)!).child("Like_Deals_Dish")
.observeSingleEvent(of: .value) { datasnapshot in
if datasnapshot.exists() {
print("Like Deals - \(datasnapshot)")
// Loop here for menu items
for rest in datasnapshot.children.allObjects as [FIRDataSnapshot] {
// Fetch Menu Info here with rest.value
Database.database().reference()
.child("menus").child(rest.value)
.observeSingleEvent(of: .value) { menu in
if datasnapshot.exists() {
print("MENU - \(menu)")
}
}
}
} else {
print("Liked data is not available")
}
}
Hope it is helpful
Upvotes: 1
Reputation: 734
You can do this without using multiple queries as suggested by Prashant. If you have a large dataset, using a query to obtain each key would be painfully slow. You could get each key like this:
Database.database().reference().child("Users").child("Consumer").child((Auth.auth().currentUser?.uid)!).child("Like_Deals_Dish").observeSingleEvent(of: .value) { datasnapshot in
if datasnapshot.exists() {
var keyArray = [String]()
for snap in datasnapshot.children.allObjects {
if let snap = snap as? DataSnapshot {
let key = snap.key
keyArray.append(key)
}
}
//use keyArray
}
else{
print("Liked data is not available")
}
}
Upvotes: 0