Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/207.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android Firebase位置查询_Android_Firebase_Location_Firebase Realtime Database - Fatal编程技术网

Android Firebase位置查询

Android Firebase位置查询,android,firebase,location,firebase-realtime-database,Android,Firebase,Location,Firebase Realtime Database,我正在用firebase在android上设计一个基于位置的餐馆搜索应用程序。firebase上的餐厅等级如下: restaurants -key address: "NYC" city: "New York" description: "" id: 60000 latitude: 39.895107 longitude: 32.797819 name: "Pizza Store" 片段类 mainActivity.mDatabase.child("restaur

我正在用firebase在android上设计一个基于位置的餐馆搜索应用程序。firebase上的餐厅等级如下:

 restaurants
-key
  address: "NYC"
  city: "New York"
  description: ""
  id: 60000
  latitude: 39.895107
  longitude: 32.797819
  name: "Pizza Store"
片段类

mainActivity.mDatabase.child("restaurants").addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot snapshot) {
            System.out.println("There are " + snapshot.getChildrenCount() + " restaurans");
            for (DataSnapshot postSnapshot : snapshot.getChildren()) {
                Restaurant post = postSnapshot.getValue(Restaurant.class);
                mapmap2.put(post.getName(), postSnapshot.getKey());
                restaurants.add(post);
            }
            adapter = new RestaurantCardViewAdapter(getActivity(), restaurants, MapListFragment.this);
            mRecyclerView.setAdapter(adapter);
        }

        @Override
        public void onCancelled(DatabaseError firebaseError) {
            System.out.println("The read failed: " + firebaseError.getMessage());
        }
    });

现在,我可以列出所有的餐馆。但我想查询用户位置。首先,我想列出用户位置附近的20家餐馆,当用户加载页面时,我想得到接下来的20家最近的餐馆。我在网上搜索。我找到了GeoFire库,但据我所知,它与firebase的遗留版本一起工作。如何使用这些标准进行查询?

Firebase查询只能按单个属性进行筛选/排序。由于位置由经度和纬度组成,因此按照您现在的格式,无法基于位置进行查询

幸运的是,有一个名为的附加库。此库将经度和纬度合并为一个名为的属性。基于此特性,它可以根据到给定位置的距离进行过滤


我建议您查看Geofire,看看它是否适合您的用例。

我在答案的帮助下解决了这个问题。我为geofire推了一个名为“餐厅位置”的单独孩子。当我插入餐厅时,我会分别推送位置

      GeoFire geoFire;
      String itemId = mDatabase.child("restaurants").push().getKey();
      mDatabase.child("restaurants").child(itemId).setValue(restaurant);

      geoFire = new GeoFire(mDatabase.child("restaurants_location"));
      geoFire.setLocation(itemId, new GeoLocation(Double.valueOf(rd.location.latitude), Double.valueOf(rd.location.longitude)));
然后,当我需要查询位置时,我使用geofire查询

    geoFire = new GeoFire(mDatabase.child("restaurants_location"));
    GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(39.896263, 32.799652), 1);

    geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
        @Override
        public void onKeyEntered(String key, GeoLocation location) {
            System.out.println(String.format("Key %s entered the search area at [%f,%f]", key, location.latitude, location.longitude));
            mDatabase.child("restaurants").child(key).addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot snapshot) {
                    Restaurant res= snapshot.getValue(Restaurant.class);
                }
                @Override
                public void onCancelled(DatabaseError firebaseError) {
                    System.out.println("The read failed: " + firebaseError.getMessage());
                }

                // ...
            });
        }

        @Override
        public void onKeyExited(String key) {
            System.out.println(String.format("Key %s is no longer in the search area", key));
        }

        @Override
        public void onKeyMoved(String key, GeoLocation location) {
            System.out.println(String.format("Key %s moved within the search area to [%f,%f]", key, location.latitude, location.longitude));
        }

        @Override
        public void onGeoQueryReady() {
            System.out.println("All initial data has been loaded and events have been fired!");
        }

        @Override
        public void onGeoQueryError(DatabaseError error) {
            System.err.println("There was an error with this query: " + error);
        }
    });

但我仍然担心这是否是从数据库中获取餐馆的最有效方法,因为我在“餐馆”根上分别为每个餐馆键运行查询。有没有人知道更有效的方法请告诉我们。

谢谢您的回答。我搜索GeoFire的属性。但我有一些疑问。建议将位置条目与餐厅分开。输入带有餐厅ID的位置信息,并查询该位置根。就像在这个链接中一样。但我不明白,当我查询位置时,我会得到最近的餐厅钥匙。在那之后,我必须用这些钥匙去餐馆。我怎么能做到这一点,这不是一个昂贵的数据库吗?事实上不是。由于使用GeoHash,GeoFire通常需要读取比返回更多的位置数据。通过让您单独查找附加信息,您实际上可能会使用更少的带宽。而且它并不像你想象的那么慢,因为Firebase通过现有的连接管道传输请求。看,是的,如果能得到一个答案会很有趣,这是最有效的方法。弗兰克·范·帕夫伦……谢谢^^