繁体   English   中英

(Android App)有没有办法在 FirebaseRecyclerOptions 查询的 SnapshotParser 部分内从 Firebase 数据库检索数据?

[英](Android App) Is there a way to retrieve data from a Firebase database while inside the SnapshotParser part of the FirebaseRecyclerOptions query?

因此,正如标题所说,在 FirebaseRecyclerOptions 中构建 object 以用于 FirebaseRecyclerAdapter 之前,我希望从 Firebase 数据库中检索数据。 基本上,我想做的是在我正在开发的应用程序中创建一个好友列表。 这是数据库的样子:

Friends:
  uid1:
    id: friendID
  uid2:
    id: friendID

Users:
  uid1:
    name: name
    status: status
    image: profileImageUrl
  uid2:
    name: name
    status: status
    image: profileImageUrl

我有目前看起来像这样的代码:

FirebaseRecyclerOptions<Users> options = new FirebaseRecyclerOptions.Builder<Users>().setQuery(usersDatabase, new SnapshotParser<Users>() {
        @NonNull
        @Override
        public Users parseSnapshot(@NonNull DataSnapshot snapshot) {
            System.out.println(snapshot);
            rootRef.child("Users").child(snapshot.getValue().toString()).addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    System.out.println(dataSnapshot);
                    name = dataSnapshot.child("name").getValue().toString();
                    status = dataSnapshot.child("status").getValue().toString();
                    image = dataSnapshot.child("image").getValue().toString();
                    return;
                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {

                }
            });
            System.out.println(snapshot);
            return new Users(name, image, status);
        }
    }).build();

问题是我添加的 ValueEventListener 直到返回新的 Users 实例后才会触发。 我应该将 ValueEventListener 添加到与 FirebaseRecyclerOptions 查询相同的 DatabaseReference (userDatabase) 吗?

使用 FirebaseUI 无法真正实现您尝试做的事情。 快照解析器需要立即或同步返回一个用户 object。 您无法执行异步数据库查询(不会立即完成,甚至根本无法保证完成)来提供该值。

如果您需要执行多个查询来填充您的视图,您将无法有效地使用 FirebaseUI。 您可能应该考虑提前进行所有查找,或者编写一个特殊的适配器,允许在结果可用时异步填充视图内容。 这最终需要大量代码才能正确完成。

回答我自己的问题似乎有点多余,但这主要适用于遇到此问题的任何其他人。 按照@Doug Stevenson 的建议,我开始尝试制作自己的自定义回收器适配器和选项 class。但是,我意识到可以修改对选项的查询。 所以基本上,解决方案是这样的:

Query query = database.collection("Users");

@Override
protected void onStart() {
    super.onStart();
    String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
    DocumentReference ref = FirebaseFirestore.getInstance().collection("Users").document(uid);
    ref.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
        @Override
        public void onComplete(@NonNull Task<DocumentSnapshot> task) {
            if (task.isSuccessful()){
                DocumentSnapshot document = task.getResult();
                if (document.exists()) {
                    friends = (ArrayList<String>) document.get("friends");
                    if (friends.size() > 0) {
                        FirestoreRecyclerOptions<Users> options = new FirestoreRecyclerOptions.Builder<Users>().setQuery(query.whereIn("user_id", friends), Users.class).build();
                        FirestoreRecyclerAdapter<Users, UsersViewHolder> adapter = new FirestoreRecyclerAdapter<Users, UsersViewHolder>(options) {
                            @Override
                            public UsersViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                                View view = LayoutInflater.from(parent.getContext())
                                        .inflate(R.layout.single_user_layout, parent, false);
                                return new UsersViewHolder(view);
                            }

                            @Override
                            protected void onBindViewHolder(@NonNull UsersViewHolder usersViewHolder, int i, @NonNull Users users) {
                                if (users != null) {
                                    usersViewHolder.setName(users.name);
                                    usersViewHolder.setStatus(users.status);
                                    usersViewHolder.setImg(users.image);

                                    final String userID = getSnapshots().getSnapshot(i).getId();
                                    usersViewHolder.mView.setOnClickListener(new View.OnClickListener() {
                                        @Override
                                        public void onClick(View view) {
                                            Intent profilePage = new Intent(FriendsList.this, ProfileActivity.class);
                                            profilePage.putExtra("userID", userID);
                                            startActivity(profilePage);
                                        }
                                    });
                                }
                            }
                        };
                        usersListPage.setAdapter(adapter);
                        adapter.startListening();
                    }
                }
            }
        }
    });
}

在 setQuery 方法中,我没有使用集合引用作为查询,而是从中创建了一个查询 object,然后修改了查询 query.whereIn(),它允许您检查文档的字段是否包含给定的object 或列表中的对象之一。

我知道我这里的代码很乱。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM