Home > database >  Getting error, foreach not applicable to type 'com.google.firebase.firestore.DocumentSnapshot&#
Getting error, foreach not applicable to type 'com.google.firebase.firestore.DocumentSnapshot&#

Time:09-24

I have added game rules in Firebase Firestore in Array format. I want to show all the strings of the array in new lines. But when I'm trying to pull the value from firebase, I'm getting this error, "foreach not applicable to type 'com.google.firebase.firestore.DocumentSnapshot'". Here's the code,

Activity

    FirebaseFirestore.getInstance().collection("categories").document(categoryId).collection("rules").document("rule").get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
        @Override
        public void onSuccess(@NonNull DocumentSnapshot documentSnapshot) {
            String data = "";
            for (QueryDocumentSnapshot doc : documentSnapshot) {
                Rules model = doc.toObject(Rules.class);
                App.logMessage("Item Added"   model.oneRule);

                for (String rule : model.getTheRules()) {
                    data  = "\n*"   rule;
                }
                //rules.add(model);
                rule.setText(data);
            }
        }
    });

Model

public class Rules {

List<String> theRules;

public Rules(List<String> theRules) {
    this.theRules = theRules;
}

public List<String> getTheRules() {
    return theRules;
}

public void setTheRules(List<String> theRules) {
    this.theRules = theRules;
}

public Rules(){}

}

Firestore screenshot enter image description here

CodePudding user response:

When you are using the following reference:

FirebaseFirestore.getInstance().collection("categories")
    .document(categoryId).collection("rules").document("rule")

It means that you are trying to read the content of a single document called "rule". When you are calling get() and attach a success listener, the argument that comes from the onSuccess() method is of type DocumentSnapshot, which isn't an iterable object. So there is no way you iterate on such an object, hence that error. If you want to map the "rule" document into an object of type "Rules", then remove the for loop and simply use:

FirebaseFirestore.getInstance().collection("categories").document(categoryId).collection("rules").document("rule").get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
    @Override
    public void onSuccess(@NonNull DocumentSnapshot documentSnapshot) {
        String data = "";
        Rules model = doc.toObject(Rules.class);
        for (String rule : model.getTheRules()) {
            data  = "\n*"   rule;
        }
        rule.setText(data);
    }
});

The result of the above lines of code will be the concatenation of all rules inside the matchRule array which will be added to the rule TextView.

The solution above will work only if you change the name of the array in the database matchRule to match the name of the list theRules in your Rules class. Or you add the following annotation in front of the getter like this:

@PropertyName("matchRule")
public List<String> getTheRules() {
    return theRules;
}

Edit:

public class Rules {

    public Rules(){}

    List<String> matchRule;

    public Rules(List<String> matchRule) {
        this.matchRule = matchRule;
    }

    public List<String> getMatchRule() {
        return matchRule;
    }

    public void setMatchRule(List<String> matchRule) {
        this.matchRule = matchRule;
    }
}
  • Related