我有用户对象如下:
{
"deviceTokens" : {
"SgJd7o1hK7YbJnygnYWvaz4qkr42" : {
"c-sfcTB3iEA:APA91bEvuzhX1nlrhoxVmR69lvwu0H1zyRjOXd5b14LngObuj8WeHkmlel6AOyrU7B2alBO1vW0pIO4gXGurvz5llCloyYpQv7vCq0_3fVEhmrIGfJ2S13TiXqVLJgWUCs95_AYZlysj" : true,
"cnQdyuxBgz0:APA91bFZTPEFrl1Vf9Nw9ZvdtNsW1ll3YYq8WIwT799NVTp6S281v56UVJ3lo0kDK_rFZfoHuarX9Qb8NL8TJXi9A_jH4RhbDp3ecbW-tHdrYR06PwYdSiMfRjIxJOuPtHuqy0TNOw4K" : true,
"d3D81crwy0E:APA91bEoAeWiOwm73bt2DvNNdv_NUn0PwjQcLa6z8ZYjDyuHWsNeDPVDCXOATKB5AFoBb7iOW6kgzU41oYFqHYek1Cngv6ArsrZO0crq_bV3PzfQxKvRN8xYX1_WryaR2tpAVP_4czgx" : true,
"dHBaxzKqhMw:APA91bGmQ5KhxiaE48_IQHEJVpvpvQdXUgAd_a1reJiyh4Z5W6dhNZB4KesaQuiRrj-VLxdCvxIroH3a-75zUaYd6_yLtoCzNfNGT8EWqUrtC3FSibOA_cwPye09C001zfFe_pHv6Wph" : true,
"dz8wf231cXE:APA91bEAmfPu4QWRstKE5kqtN-UtgNpOIG7KWxsjFB1oIOp9cKhoWfbnpsvMTd3YgNw09jVNK6lUgKXMNt4AND0cZGcepkqQyZTDNh5KA5SU9KbbD7MJzxGhwGhGlFV-4hiOOhumoRxs" : true
}
},
"users" : {
"SgJd7o1hK7YbJnygnYWvaz4qkr42" : {
"displayName" : "Chintan Soni",
"email" : "chintansoni202@gmail.com",
"photoUrl" : "https://lh5.googleusercontent.com/-JNfSscqwEng/AAAAAAAAAAI/AAAAAAAADbs/dj7t_7AYlzo/s96-c/photo.jpg"
}
}
}
我可以使用以下方式查询Users对象:
mDatabaseReference = FirebaseDatabase.getInstance().getReference().child("users");
我想知道无论如何都要查询不平等。我想查询用户的孩子的密钥与我的FirebaseUser UID不匹配,意味着我想获取除了我的用户的记录。
答案 0 :(得分:3)
实际上,我并不想创建自己的适配器,因为我相信FirebaseUI不会有这样的限制,但我错了。 无论如何,这就是我接近的方式:
首先从FirebaseDatabase中获取用户对象中的所有数据,然后在我们的末尾进行过滤,最后设置该数据:
FirebaseDatabase.getInstance().getReference().child("users")
.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Iterable<DataSnapshot> list = dataSnapshot.getChildren();
// Getting current user Id
String uid = getCurrentUserId();
// Filter User
List<User> userList = new ArrayList<>();
for (DataSnapshot dataSnapshot1 : list) {
if (!dataSnapshot1.getKey().equals(uid)) {
userList.add(dataSnapshot1.getValue(User.class));
}
}
// Setting data
mBaseRecyclerAdapter.setItems(userList);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
我在这里创建了自己的通用回收器适配器: https://gist.github.com/chintansoni202/3c61aea787ae4bd49f26adee9dd40a08
答案 1 :(得分:2)
解决此问题并仍然使用FirebaseUI中的FirebaseRecyclerAdapter的一种方法是扩展FirebaseArray,如下所示:
import com.firebase.ui.database.FirebaseArray;
import com.firebase.ui.database.SnapshotParser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.Query;
import java.util.HashSet;
import java.util.Set;
public class FilterableFirebaseArray extends FirebaseArray {
private Set<String> excludes = new HashSet<>();
public FilterableFirebaseArray(Query query, Class aClass) {
super(query, aClass);
}
public FilterableFirebaseArray(Query query, SnapshotParser parser) {
super(query, parser);
}
public void addExclude(String key) {
excludes.add(key);
}
public void removeExclude(String key) {
excludes.remove(key);
}
@Override
public void onChildAdded(DataSnapshot snapshot, String previousChildKey) {
if (!excludes.contains(snapshot.getKey())) {
super.onChildAdded(snapshot, excludes.contains(previousChildKey)? null : previousChildKey);
}
}
@Override
public void onChildChanged(DataSnapshot snapshot, String previousChildKey) {
if (!excludes.contains(snapshot.getKey())) {
super.onChildChanged(snapshot, excludes.contains(previousChildKey)? null : previousChildKey);
}
}
@Override
public void onChildMoved(DataSnapshot snapshot, String previousChildKey) {
if (!excludes.contains(snapshot.getKey())) {
super.onChildMoved(snapshot, excludes.contains(previousChildKey)? null : previousChildKey);
}
}
@Override
public void onChildRemoved(DataSnapshot snapshot) {
if (!excludes.contains(snapshot.getKey())) {
super.onChildRemoved(snapshot);
}
}
}
...然后像这样使用它:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView userListView = (RecyclerView) findViewById(R.id.userList);
userListView.setLayoutManager(new LinearLayoutManager(this));
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
Query query = ref.orderByValue();
ClassSnapshotParser parser = new ClassSnapshotParser<UserProfile>(UserProfile.class);
FilterableFirebaseArray filterableFirebaseArray = new FilterableFirebaseArray(query, parser);
filterableFirebaseArray.addExclude(FirebaseAuth.getInstance().getCurrentUser().getUid());
FirebaseRecyclerAdapter mAdapter = new FirebaseRecyclerAdapter<UserProfile, UserListEntryHolder>(
filterableFirebaseArray,
R.layout.userlist_entry,
UserListEntryHolder.class) {
@Override
protected void populateViewHolder(UserListEntryHolder viewHolder, UserProfile model, int position) {
viewHolder.bind(model);
}
};
userListView.setAdapter(mAdapter);
}
“魔法”发生在重写的onChildAdded方法中,我们忽略由指定键标识的子节点。在此示例中,我只是将当前用户的UID添加到排除列表中。因为这符合我的数据库设计。
您可以轻松扩展功能,以忽略具有特定属性的子项。
奖金:如果您更喜欢Kotlin方式(就像我一样),您就是这样做的:
import com.firebase.ui.database.FirebaseArray
import com.firebase.ui.database.SnapshotParser
import com.google.firebase.database.DataSnapshot
import com.google.firebase.database.Query
class FilterableFirebaseArray<T> : FirebaseArray<T> {
val excludedKeys = HashSet<String?>()
constructor(query: Query, tClass: Class<T>) : super(query, tClass)
constructor(query: Query, parser: SnapshotParser<T>) : super(query, parser)
override fun onChildAdded(snapshot: DataSnapshot, previousChildKey: String?) {
if (!excludedKeys.contains(snapshot.key))
super.onChildAdded(snapshot, if (excludedKeys.contains(previousChildKey)) null else previousChildKey)
}
override fun onChildChanged(snapshot: DataSnapshot, previousChildKey: String?) {
if (!excludedKeys.contains(snapshot.key))
super.onChildChanged(snapshot, previousChildKey)
}
override fun onChildMoved(snapshot: DataSnapshot, previousChildKey: String?) {
if (!excludedKeys.contains(snapshot.key))
super.onChildMoved(snapshot, previousChildKey)
}
override fun onChildRemoved(snapshot: DataSnapshot) {
if (!excludedKeys.contains(snapshot.key))
super.onChildRemoved(snapshot)
}
}
...然后像这样使用它:
override fun onStart() {
super.onStart()
if (currentUser != null) {
userList.adapter = getAdapter()
}
}
private fun getAdapter(): FirebaseRecyclerAdapter<UserProfile, UserListEntryHolder> {
val query = userProfilesReference.orderByValue()
val parser = ClassSnapshotParser<UserProfile>(UserProfile::class.java)
val filterableFirebaseArray = FilterableFirebaseArray<UserProfile>(query, parser)
filterableFirebaseArray.excludes.add(currentUser?.uid)
return object : FirebaseRecyclerAdapter<UserProfile, UserListEntryHolder>(
filterableFirebaseArray,
R.layout.userlist_entry,
UserListEntryHolder::class.java) {
public override fun populateViewHolder(entryHolder: UserListEntryHolder, userProfile: UserProfile, position: Int) {
entryHolder.bind(userProfile)
}
}
}
更新了解决与onChildChanged,onChildMoved等相关的IllegalArgumentExceptions的代码。