2

I have the following structure of my Firestore database:

products:{ // Collection
    procuct_1: { // Document
       title:"",
       url:""

videos:{ // Collection
    video_1:{ // Document
       title:"",
       products:{ // Array of references 
            0: "/products/product_1,
            1: "/products/product_2

I would like to be able from Array field in Videos Collection to get Document References to Products collection in order to get values of some fields of this collection (ex. title of product).

For the moment I use this code:

    FirebaseFirestore firebaseFirestore = FirebaseFirestore.getInstance();
    firebaseFirestore
            .collection("videos")
            .get()
            .addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
                @Override
                public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                    if (task.isSuccessful()) {
                        DocumentSnapshot documentSnapshot = task.getResult();

                        Map<String, Object> map = documentSnapshot.getData();
                        for (Map.Entry<String, Object> entry: map.entrySet()){
                            if (entry.getKey().equals("products")){
                               textView.setText(entry.getValue().toString());
                            }
                        }

But entry.getValue().toString(), returns me such array:

[com.google.firebase.firestore.DocumentReference@451d5ae8,

com.google.firebase.firestore.DocumentReference@e28cd0c]

Any suggestions how I can get any field of Product collection from this Array?

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
Kiwi
  • 173
  • 2
  • 9

2 Answers2

1

To solve this, please use the following code:

firebaseFirestore.collection("videos")
    .get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
        @Override
        public void onComplete(@NonNull Task<QuerySnapshot> task) {
            for (DocumentSnapshot document : task.getResult()) {
                List<String> products = (List<String>) document.get("products");
                for (String product : products) {
                    Log.d("TAG", product);
                }
            }
        }
    });

The output will be:

/products/product_1
/products/product_2
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Thanks for your answer. But I am getting an error _java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.util.Map_ on this line of code `Map products = (Map) document.get("products");` – Kiwi Mar 28 '18 at 09:39
  • Sorry for my late answer. I didn't see the brackets in your database structure so I thought it is a `Map` and that's why that error. Please see my updated answer. It works for sure now. – Alex Mamo Mar 28 '18 at 11:47
1

This code allowed me to reach the result that I needed

FirebaseFirestore firebaseFirestore = FirebaseFirestore.getInstance();
    firebaseFirestore
            .collection("videos")
            .get()
            .addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
                @Override
                public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                    DocumentSnapshot document = task.getResult();
                    ArrayList<DocumentReference> products = (ArrayList<DocumentReference>) document.get("products");
                    for (int i = 0; i < products.size(); i++) {
                        DocumentReference ref = products.get(i);
                        ref.get()
                                .addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
                                    @Override
                                    public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                                        if (task.isSuccessful()) {
                                            DocumentSnapshot document = task.getResult();
                                            if (document != null && document.exists()) {
                                                BestBuysProducts best_buy = document.toObject(BestBuysProducts.class);
                                                Log.d(TAG, "Title: " + best_buy.getProduct_title());
                                            }
                                        }
                                    }
                                });
                    }
                }
            });
Kiwi
  • 173
  • 2
  • 9
  • I see that is working but what you are doing is not a good practice because you are attaching a listener for every iteration of that loop. So keeping listeners for data you don't need to keep it synchronized is wasteful. Please see my updated answer using only a few lines of code. – Alex Mamo Mar 28 '18 at 11:46
  • Good to hear that it worked! If you think that my answer helped you, please consider accepting it. Thanks! – Alex Mamo Mar 29 '18 at 16:03