【问题标题】:Trying to retrieve field from one collection based on UID of two collections matching尝试根据两个集合匹配的 UID 从一个集合中检索字段
【发布时间】:2019-01-28 16:58:25
【问题描述】:

我正在尝试从出勤集合和学生集合中检索其 userUID 匹配的每个学生的姓名,即如果两个用户 UID 匹配,我想从学生集合中返回与 userUID 关联的名称。我正在查询出勤表开始。

这是我的代码:

public void viewAttendance(View v) {
    attendanceRef2.orderBy("sessionID", Query.Direction.ASCENDING)
            .get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
        @Override
        public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
            String data = "";

            for (QueryDocumentSnapshot documentSnapshot : queryDocumentSnapshots) {
                Attendance attendance = documentSnapshot.toObject(Attendance.class);
                Student studentName = documentSnapshot.toObject(Student.class);

                String sessionID = attendance.getSessionID();
                String studentID = attendance.getUserUID();
                String attendanceUID = studentName.getUserUID();
                String name;

                if (studentID.equals(attendanceUID)){

        name = studentName.getName();
                    data+= "Session ID: " + sessionID + "\n" + "Student Name: " + name + "\n\n";
                }
            }
            textViewData.setText(data);
        }
    });
}

编辑代码

public void viewAttendance(View v) {
    attendanceRef2.orderBy("sessionID", Query.Direction.ASCENDING)
            .get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
        @Override
        public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
            String data = "";

            for (QueryDocumentSnapshot documentSnapshot : queryDocumentSnapshots) {
                Attendance attendance = documentSnapshot.toObject(Attendance.class);
                Student studentName = documentSnapshot.toObject(Student.class);

                String sessionID = attendance.getSessionID();
                String attendanceUID = attendance.getUserUID();
                String studentUID = studentName.getUserUID();
                final String name = "";

                if (attendanceUID.equals(studentUID)){
                    db.collection("Student").document("name").get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
                        @Override
                        public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                            textViewData.setText(name);
                        }
                    });

                }
                data+= "Session ID: " + sessionID + "\n" + "Student Name: " + name + "\n\n";
            }
            textViewData.setText(data);
        }
    });
}

【问题讨论】:

  • 虽然在学生姓名中返回 null,但目前正在检索会话 ID
  • 您正在从现在拥有的代码中的单个集合中加载单个文档。如果您想从不同的集合中加载学生,则必须在循环内使用另一个 get() 来执行此操作,例如:db.collection("Users").document(studentID).get().addOnCompleteListener(...
  • 这是我添加您的建议的地方。它检索 sessionID 然后消失,什么都没有显示?
  • 您需要一个onSuccess,就像您喜欢的外部听众一样。然后在那个新的 onSuccess 中加载用户信息,从您使用Student studentName = documentSnapshot.toObject(Student.class); 加载的新文档中加载
  • 所以我必须在 for 循环中或在查询之前插入它

标签: android google-cloud-firestore


【解决方案1】:

你越来越近了。您需要加载两个文档:

  1. 考勤信息
  2. 学生的用户信息

由于用户名来自第二个文档,因此您只能在加载第二个文档后调用DocumentSnapshot.toObject(因此在第二个侦听器的onCompleteonSuccess 回调中)。比如:

public void viewAttendance(View v) {
  attendanceRef2.orderBy("sessionID", Query.Direction.ASCENDING)
        .get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
    @Override
    public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
        String data = "";

        for (QueryDocumentSnapshot documentSnapshot : queryDocumentSnapshots) {
            Attendance attendance = documentSnapshot.toObject(Attendance.class);

            String sessionID = attendance.getSessionID();
            String attendanceUID = attendance.getUserUID();
            String studentUID = studentName.getUserUID();

            if (attendanceUID.equals(studentUID)){
                db.collection("Student").document(studentUID).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
                    @Override
                    public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                        Student studentName = task.getResult().toObject(Student.class);
                        textViewData.setText(studentName);
                        // Or maybe: textViewData.setText(studentName.getName());

                        data+= "Session ID: " + sessionID + "\n" + "Student Name: " + studentName + "\n\n";
                        textViewData.setText(data);
                    }
                });

            }
        }
    }
  });
}

【讨论】:

  • 尝试打印数据时的 name 变量让我感到困惑弗兰克,if 语句完成后如何根据用户 UID 获取名称。
  • 啊哈...我错过了这些台词。由于它们需要名称(仅在第二个文档也加载后才可用),因此它们需要 inside 第二个回调。我更新了我的答案。
  • 使用这个更新的解决方案我在 logcat 中遇到运行时错误,它指向这一行 textViewData.setText(studentName);
  • 它表示尝试在空对象引用上调用虚拟方法
  • 当我搜索学生集合然后使用 .document("name") 是否暗示该名称是一个文档。因为我正在寻找学生的姓名,这是学生集合中保存的文档中的一个字段
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-01
  • 2014-04-19
相关资源
最近更新 更多