在Android中填充viewHolder之前,按特定条件过滤geoFire查询

Att*_*s29 4 android event-listener firebase geofire firebase-realtime-database

我已经成功实现了geoFire,以从用户区域内的主要firebase节点获取条目的密钥.

然后我尝试将这些密钥存储在一个新的唯一节点中,以便稍后使用它们来填充viewHolder,因为这似乎是最佳实践.

问题是我不希望存储在唯一节点中的所有对象实际填充viewHolder; 我只想要它们的一部分.

如果我在populateViewHolder方法中进行过滤,例如,

@Override
public void onDataChange(DataSnapshot dataSnapshot) {
    SwarmReport retrievedModel = dataSnapshot.getValue(SwarmReport.class);
    if(!retrievedModel.isClaimed()){
        viewHolder.bindSwarmReport(retrievedModel);
    }
}
Run Code Online (Sandbox Code Playgroud)

我在viewHolder中得到了一些空白的项目.

相反,如果我在设置FirebaseAdapter之前尝试过滤,例如在我的addGeoQueryEventListener方法中,我必须添加一个addListenerForSingleValueEvent来检查我希望过滤的标准:

public void onKeyEntered(String key, GeoLocation location) {
    claimCheckKey = key;
    final DatabaseReference claimCheckRef = FirebaseDatabase.getInstance().getReference("all").child(key);
    claimCheckRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            SwarmReport claimCheckSwarmReport = dataSnapshot.getValue(SwarmReport.class);
            if (!claimCheckSwarmReport.isClaimed()){
                swarmReportIds.add(claimCheckKey);
            }
        }
Run Code Online (Sandbox Code Playgroud)

似乎在完成onGeoQueryReady之前执行.有关如何等待所有swarmReportIds.add(claimCheckKey)完成的任何建议?addListenerForSingleValueEventonKeyEnteredonGeoQueryReady

如果它有用,这里是我的firebase结构的快照: 在此输入图像描述

oma*_*A.R 5

我真的不明白你想要实现的目标,但我会猜测并说你不仅想要最接近key但你也想key根据其他一些标准过滤最接近的标准,例如最近的餐馆然后价格,

我为实现这个目的所做的解决方法(仍然在寻找更好的选项)是在onDatachange方法内部设置一个标志,我在onKeyentered方法内部调用,比较该节点内的条目,(为了论证我们会说价格)

UPDATE

  @Override
        public void onKeyEntered(final String key, GeoLocation location) {
     final DatabaseReference db = FirebaseDatabase.getInstance().getReference("<your ref>"+key);
     db.addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {


                    for (DataSnapshot ds : dataSnapshot.getChildren()) {


                        String dishPrice=ds.getValue(String.class);
                        int price=Integer.parseInt(dishPrice);



                            if (price<=12) {

                                isMatch=true;

                            }


                    }
                    if(isMatch){
                        getRestaurants(key);
                    }
                    isMatch=false;


                }
Run Code Online (Sandbox Code Playgroud)

onDataChange我设置的每个循环之外执行只在函数为真时填充arraylistmy adapter的函数

getRestaurants方法

    private void getRestaurants(final String id) {

   final DatabaseReference temp=FirebaseDatabase.getInstance().getRef("<your 
 ref>"+id)
          temp.child(id).addListenerForSingleValueEvent(new 
          ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {


                    Restaurant restaurant = dataSnapshot.getValue(Restaurant.class);  
                    restaurant.setName(restaurant.getName());
                    restaurant.setImageUri(restaurant.getImageUri());
                    restaurant.setUid(id);


                    //add elemens to arraylist


                        resList.add(restaurant);
                        adapter.notifyDataSetChanged();


                }
Run Code Online (Sandbox Code Playgroud)

另一个建议是使云上的一个功能,你的情况(再次假设),所有你需要的是监测的值是否"爆料"的变化,所以你可以设置一个onUpdate事件触发或与onWrite并检查值onChanged()和获取当前值(true/false)之后,您可以使用geoFire查询并获取用户关闭并根据值更新其节点.

事件触发器

云功能