Android应用程序在FirebaseRecyclerOptions查询的SnapshotParser部分中,是否有办法从Firebase数据库检索数据?

问题描述

因此,正如标题所述,我希望在FirebaseRecyclerOptions中构造要在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确实无法实现您要执行的操作。快照解析器需要立即或同步返回用户对象。为了提供该值,您无法执行异步数据库查询(该查询不会立即完成,甚至无法保证完全完成)。

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

,

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

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方法中,我没有使用集合引用作为查询,而是从中创建了一个查询对象,然后修改了查询query.whereIn(),该方法可让您检查文档的字段是否包含给定对象或列表中的对象之一。

我知道我的代码很乱。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...