【问题标题】:android firebase : NOT EQUAL query in Firebase Databaseandroid firebase:Firebase 数据库中的 NOT EQUAL 查询
【发布时间】:2017-09-06 19:04:02
【问题描述】:

我有如下用户对象:

{
  "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"
    }
  }
}

我可以使用以下方法查询用户对象:

mDatabaseReference = FirebaseDatabase.getInstance().getReference().child("users");

我想知道是否有查询不等式的方法。我想查询用户的孩子的密钥与我的 FirebaseUser UID 不匹配,这意味着我想获取除我之外的用户的记录。

【问题讨论】:

标签: android firebase firebase-realtime-database


【解决方案1】:

其实我并不想创建自己的适配器,因为我相信 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

【讨论】:

    【解决方案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。

    【讨论】:

    • 你好 Henrik,当我尝试扩展 FirebaseArray 时,它没有找到它来导入包或任何东西。你知道为什么它不让我延长它吗谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多