问题描述
因此,正如标题所述,我希望在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(),该方法可让您检查文档的字段是否包含给定对象或列表中的对象之一。
我知道我的代码很乱。