ajeet sharma
ajeet sharma

Reputation: 843

How to Fetch Firebase Database for Only Selected List of Keys in Swift?

I am using firebase database for storing data of my iOS application.

Here is my firebase database high level structure:

enter image description here

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:

enter image description here

There is one more node "Users" and it has one child "Consumer"

enter image description here

I am saving 'liked' and 'disliked' menu item in different children of "Consumer" node. enter image description here

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:

enter image description here

What should be the query to fetch only those menuItems whose keys are added in the "Like_Deal_Dish" ?

Upvotes: 4

Views: 1936

Answers (3)

Shriyansh Mahajan
Shriyansh Mahajan

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

Prashant Tukadiya
Prashant Tukadiya

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

pho_pho
pho_pho

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

Related Questions