Android/FireStore 查询和返回自定义对象

3
我有一个关于Firestore和Android/Java实现的问题,这次涉及代码。这是我的数据库外观:

enter image description here 它将成为一个QuizApp,数据库包含一个生成的ID和一个customObject(type: questionDataObject name: content),还有一个数组列表,具有以下限制/想法:

[0]: 问题
1: 正确答案
[2]...[4] 错误答案

我在questionDataObject中添加了一个字符串“number”,只是为了有些简单的东西,我可以搜索/查询。这就是我的问题,我无法让查询工作。
    public class questionAdder extends AppCompatActivity {

    EditText pQuestion, pAnwerA, pAnswerB, pAnswerC, pAnswerD, number;
    Button pAdd, query;
    private DatabaseReference databaseReference;
    private FirebaseFirestore firebaseFirestore;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.addquestion);

        firebaseFirestore = FirebaseFirestore.getInstance();

        pQuestion = (EditText) findViewById(R.id.question);
        pAnwerA = (EditText) findViewById(R.id.answerA);
        pAnswerB = (EditText) findViewById(R.id.answerB);
        pAnswerC = (EditText) findViewById(R.id.answerC);
        pAnswerD = (EditText) findViewById(R.id.answerD);
        number = (EditText) findViewById(R.id.number);

        pAdd = (Button) findViewById(R.id.addQuestion);
        pAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                readQuestionStore();
            }
        });

        query = (Button) findViewById(R.id.query);
        query.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                CollectionReference questionRef = firebaseFirestore.collection("questions");
                com.google.firebase.firestore.Query query = questionRef.whereEqualTo("content.number", "20");
                query.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
                    @Override
                    public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
                        //questionObject content = queryDocumentSnapshots.toObjects(questionObject.class);
                    }
                });
            }
        });
    }

    public void readQuestionStore(){
        ArrayList<String> pContent = new ArrayList<>();
        pContent.add(0, pQuestion.getText().toString());
        pContent.add(1, pAnwerA.getText().toString());
        pContent.add(2, pAnswerB.getText().toString());
        pContent.add(3, pAnswerC.getText().toString());
        pContent.add(4, pAnswerD.getText().toString());
        questionObject content = new questionObject(pContent, number.getText().toString()); //document("Essen").collection("Katalog")
       firebaseFirestore.collection("questions").add(content).addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
            @Override
            public void onSuccess(DocumentReference documentReference) {
                Toast.makeText(questionAdder.this, "Klappt", Toast.LENGTH_LONG).show();
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Toast.makeText(questionAdder.this, "Klappt nicht", Toast.LENGTH_LONG).show();
            }
        });
    }
}


public class questionObject{
    private ArrayList<String> content;
    private String number;

    public questionObject(){

    }

    public questionObject(ArrayList<String> pContent, String pNumber) {
        this.content = pContent;
        this.number = pNumber;
    }

        public ArrayList<String> getContent() {
            return content;
        }

        public void setContent(ArrayList<String> content) {
            this.content = content;
        }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }
}


这个应用程序并不是我想要发布的,我只是想练习Firebase Firestore编码等。

问题: 我如何从数据库中获取对象,并且如何检查查询是否成功?我实际上无法看到查询是否找到了我的条目。我唯一的反馈是云引擎添加了一个“读取”操作。

谢谢!




1个回答

5

首先,我建议您浏览一下Firestore文档,该文档将指导您如何从Cloud Firestore数据库中获取数据。

如果您跳转到自定义对象部分,您将看到以下代码片段:

DocumentReference docRef = db.collection("cities").document("BJ");
docRef.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
    @Override
    public void onSuccess(DocumentSnapshot documentSnapshot) {
        City city = documentSnapshot.toObject(City.class);
    }
});

这是如何将您收到的文档快照转换为自定义对象的方法。在转换中,您需要将City.class改为您的对象,即questionObject.class
此外,您不能在自定义对象的属性中使用Array List,因为Firebase 模块无法读取它。相反,您需要使用一个Map对象,是 Map 对象 - 一个集合,它有一个key和一个value,就像 Firestore document中的字段名和值一样。
您可以在上面的 Firestore 文档中看到,在Example Data部分下,他们展示了一个Map示例:
Map<String, Object> data1 = new HashMap<>();
data1.put("name", "San Francisco");
data1.put("state", "CA");
data1.put("country", "USA");
data1.put("capital", false);
data1.put("population", 860000);

这就是为什么你的content属性应该像这样:

Map<Integer, Object> content = new HashMap<>();
content.put(0, "a");
content.put(1, "a");
content.put(2, "a");
content.put(3, "a");

此外,您可以将QueryGet请求组合成一行代码:
CollectionReference questionRef = firebaseFirestore.collection("questions");
questionRef.whereEqualTo("content.number", "20").get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
    @Override
    public void onSuccess(QuerySnapshot queryDocumentSnapshots) {

    }
});

谢谢您的快速回复。我已经找到了有关获取数据的部分,但我不确定如何将查询与其结合起来。我在按钮查询的 On Click 监听器中有那段代码,这理论上是正确的吗?我划掉了 .toObject 部分,因为我确实收到了一个不兼容的 ArrayList 错误。我打算删除数组并添加哈希映射作为第一步! - J. Lo
是的,将您的监听器放在 OnClickListener 中是一种选择。如果有更多代码需要执行,它也可以在一个单独的 method 中。确保在请求开始时显示进度条,并在完成时禁用它,以便用户知道其状态。 - Tal Barda
哦,抱歉,我表述不清楚。我想问的是OnClickListener中的查询和获取命令是否正确。Firebase文档只提供了Get Only或Query Only示例,但我想要查询和获取。抱歉,我不是母语使用者,希望现在我能更好地描述它。 - J. Lo
@J.Lo,我已经编辑了我的答案并添加了查询和获取的组合版本。希望它能回答你的问题。你可以将它放在你的OnClickListener中。 - Tal Barda
我现在已经更改了questionObject,它获取数字和HashMap。我还编辑了Query-Button-OnClickListenor,但是当尝试将Snapchot转换为我的对象:questionObject pContent = queryDocumentSnapshots.toObjects(questionObject.class); 它给出了不兼容类型错误。发现java.util.list和所需的:questionObject。 - J. Lo
@J.Lo,我认为使用你的新代码提出一个新问题会更好,这样我们可以更好地理解你的问题并提供帮助。这个问题已经有了答案,从你的评论中很难理解出错了什么。 - Tal Barda

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接