3

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?

2 Answers 2

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
Sign up to request clarification or add additional context in comments.

2 Comments

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<String, Object> products = (Map<String, Object>) document.get("products");
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.
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());
                                            }
                                        }
                                    }
                                });
                    }
                }
            });

2 Comments

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.
Good to hear that it worked! If you think that my answer helped you, please consider accepting it. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.