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(){}
}
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;
}
}