本文介绍了如何检索我的范围内0.5公里内的帖子?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我正在保存用户发布的帖子的坐标。我生成一个推送ID,然后使用它来保存帖子和geofire坐标的数据。 我只想显示0.5以内的帖子公里他们的半径。我正在使用 GeoFire 库,但我无法完成任务。 生成推式ID: itemID = databaseReferenceRequests.push().getKey(); m使用它来保存geofire的坐标以及帖子的数据: $ b $ p $ ge $ F $ ge $ geoFire.setLocation(itemID,new GeoLocation(Double.parseDouble( ();}}; 和 databaseReferenceRequests.child(itemID).setValue(hRequest); p> 问题是,当我试图只抓取那些距离我的0.5公里范围内的帖子,不会发生,所有的帖子也不在附近或远得到检索。 以下是我如何检索它: public void retrieveHelpRequests(){ geoQuery = geoFire.queryAtLocation(new GeoLocation(currentLatDouble,currentLngDouble),0.5); geoQuery.addGeoQueryEventListener(new GeoQueryEventListener(){ @Override $ b $ public void onKeyEntered(String key,GeoLocation location){ databaseReference.child(help-requests ).addListenerForSingleValueEvent(new ValueEventListener(){ @Override public void onDataChange(DataSnapshot dataSnapshot){ Map< String,String> newRequest =(Map< String,String>)dataSnapshot。 getValue(); imageUID = newRequest.get(imageUIDh); homelessDescription = newRequest.get(homelessDescription); currentLat = newRequest.get(currentLat); currentLng = newRequest.get(currentLng); postedBy = newRequest.get(postingBy); postedAtTime = newRequest.get(postedAtTi我); postedOnDate = newRequest.get(postedOnDate); utcFormatDateTime = newRequest.get(utcFormatDateTime); String timeStr = utcFormatDateTime; SimpleDateFormat df = new SimpleDateFormat(yyyy-MM-dd HH:mm:ss); df.setTimeZone(TimeZone.getTimeZone(UTC)); 日期日期=空; 尝试{ // 下面的错误日期= df.parse(timeStr); } catch(ParseException e){ e.printStackTrace(); } df.setTimeZone(TimeZone.getDefault()); final String persisted = df.format(date); //从DB解析字符串 - UTC时区解析的日期=空; try { parsed = df.parse(persisted); } catch(ParseException e){ e.printStackTrace(); } //现在转换为任何时区用于显示目的 final SimpleDateFormat displayFormat = new SimpleDateFormat(h:mm a); displayFormat.setTimeZone(TimeZone.getDefault()); formattedTime = displayFormat.format(parsed); prepareDataForRequests(); $ b @Override public void onCancelled(DatabaseError databaseError){ Snackbar snackbar = Snackbar .make(coordinatorLayout,databaseError.getMessage(), Snackbar.LENGTH_LONG); snackbar.setDuration(Snackbar.LENGTH_SHORT); snackbar.show(); // helpRequestsLoadingDialog.dismiss(); progressBarLoadingRequests.setVisibility(View.INVISIBLE); } }); databaseReference.child(help-requests)。addValueEventListener(new ValueEventListener(){ @Override public void onDataChange(final DataSnapshot dataSnapshot){ / / adView.loadAd(request); card_ads2.setVisibility(View.VISIBLE); adView2.loadAd(request2); if(snackbar!= null){ snackbar。 (); } progressBarLoadingRequests.setVisibility(View.INVISIBLE); $ b $ if(fastItemAdapter.getAdapterItemCount()== 0){ emptyRVtext.setVisibility View.VISIBLE); emptyRVtexthh.setVisibility(View.VISIBLE); card_ads2.setVisibility(View.INVISIBLE); } else { emptyRVtext.setVisibility(View.INVISIBLE); emptyRVtexthh.setVisibility(View.INVISIBLE); } // progressBarLoadingRequests.setVisibility(View.INVISIBLE); $ b @Override public void onCancelled(DatabaseError databaseError){ Snackbar snackbar = Snackbar .make(coordinatorLayout,databaseError.getMessage(), Snackbar.LENGTH_LONG); snackbar.setDuration(Snackbar.LENGTH_SHORT); snackbar.show(); // hRequestsLoadingDialog.dismiss(); progressBarLoadingRequests.setVisibility(View.INVISIBLE); } }); } @Override public void onKeyExited(String key){ } @Override public void onKeyMoved(String key,GeoLocation location){ } @Override public void onGeoQueryReady(){ } @Override public void onGeoQueryError(DatabaseError error){ Toast.makeText(getBaseContext(),Error geoquery返回地理查询,Toast.LENGTH_SHORT).show(); } }); $ b 这里是错误: java。 lang.NullPointerException:尝试对空对象引用虚拟方法'int java.lang.String.length()'引用 请让我知道如何检索那些在用户0.5公里内的帖子? 解决方案这个我无能为力,但是从GeoFire 2.0页面看这个提取的代码。这里给出了一个很好的大纲在JavaScript(而不是Java)你正在寻找什么。 GeoFire的真实效用通过创建一个GeoQuery来显示。假设您正在为自行车运动员制作应用程序,该应用程序会在用户当前位置的1英里(1.609公里)范围内显示自行车商店。您需要做的第一件事就是将您关心的自行车店添加到GeoFire。然后,创建一个以用户当前位置为中心的查询(假设他们在[37.4,-122.6]): var geoQuery = geoFire.query({ center:[37.4,-122.6], radius:1.609 // km }); 查询本身不是很有用。但是,GeoFire允许您添加重要查询事件发生时触发的回调函数。由于您要显示与查询条件相匹配的每个自行车商店,请监听key_entered事件。每当一个关键字(即自行车店)进入查询时,您定义的回调函数将被调用关于该位置的数据: geoQuery.on(key_entered,function(key,location,distance){ console.log(自行车店+ key +found at + location + (+距离+公里以外)); }); 认识到key_entered事件与典型的Firebase事件。也就是说,GeoFire中每个与查询条件相匹配的键都会被触发,这两个键都已经在GeoFire中,以及在将来任何时候添加的键。感谢Firebase,您会实时收到这些事件。 GeoFire在查询中如何查找关键字非常聪明。它不需要将所有的GeoFire数据加载到内存中。如果您的用户在旧金山寻找自行车商店,GeoFire将不会加载位于纽约的地点的数据,只会意识到他们位于该国的对面。它只检查实际附近的位置。这使您的应用程序轻而易举,无论您的数据集有多大。 如果您的用户在寻找商店访问时骑自行车,距离它们一英里以内的商店现在更远。为了解决这个问题,GeoFire会为每个留下查询的键激发key_exited事件: geoQuery.on(key_exited,function(key,location,distance){ console.log(自行车店+ key +左侧查询到+ location +(+ distance +km away )); }); 这就是让您的应用程序工作所需的全部功能。对于Java可用的细节似乎更稀疏,但是对于你正在尝试做的事情,似乎是这样的:$ / $> GeoQuery geoQuery = geoFire.queryAtLocation(currentUserLocation,1.6); 参考这里。 I am saving the coordinates of the post posted by the users. I'm generating a push id and then using it to save both the data of the post and the geofire coordinates.I want to show only those posts which are within 0.5 kms radius of them. I am using GeoFire library for the same but I'm unable to achieve the task.Here's how I'm generating the push id: itemID = databaseReferenceRequests.push().getKey();Here's how I'm using it to save geofire coordinates as well as the data of the posts: geoFire.setLocation(itemID, new GeoLocation(Double.parseDouble(currentLat.getText().toString()), Double.parseDouble(currentLng.getText().toString())));and databaseReferenceRequests.child(itemID).setValue(hRequest);It is getting saved like this:The problem is that when I'm trying to fetch only those posts which are within 0.5 kms of my reach, it is not happening and all the posts whether near or far are getting retrieved.Here's how I'm retrieving it:public void retrieveHelpRequests() { geoQuery = geoFire.queryAtLocation(new GeoLocation(currentLatDouble, currentLngDouble), 0.5); geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() { @Override public void onKeyEntered(String key, GeoLocation location) { databaseReference.child("help-requests").addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { Map<String, String> newRequest = (Map<String, String>) dataSnapshot.getValue(); imageUID = newRequest.get("imageUIDh"); homelessDescription = newRequest.get("homelessDescription"); currentLat = newRequest.get("currentLat"); currentLng = newRequest.get("currentLng"); postedBy = newRequest.get("postedBy"); postedAtTime = newRequest.get("postedAtTime"); postedOnDate = newRequest.get("postedOnDate"); utcFormatDateTime = newRequest.get("utcFormatDateTime"); String timeStr = utcFormatDateTime; SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); df.setTimeZone(TimeZone.getTimeZone("UTC")); Date date = null; try { // error on line below date = df.parse(timeStr); } catch (ParseException e) { e.printStackTrace(); } df.setTimeZone(TimeZone.getDefault()); final String persisted = df.format(date); // Parse string from DB - UTC timezone Date parsed = null; try { parsed = df.parse(persisted); } catch (ParseException e) { e.printStackTrace(); } // Now convert to whatever timezone for display purposes final SimpleDateFormat displayFormat = new SimpleDateFormat("h:mm a"); displayFormat.setTimeZone(TimeZone.getDefault()); formattedTime = displayFormat.format(parsed); prepareDataForRequests(); } @Override public void onCancelled(DatabaseError databaseError) { Snackbar snackbar = Snackbar .make(coordinatorLayout, databaseError.getMessage(), Snackbar.LENGTH_LONG); snackbar.setDuration(Snackbar.LENGTH_SHORT); snackbar.show();// helpRequestsLoadingDialog.dismiss(); progressBarLoadingRequests.setVisibility(View.INVISIBLE); } }); databaseReference.child("help-requests").addValueEventListener(new ValueEventListener() { @Override public void onDataChange(final DataSnapshot dataSnapshot) { // adView.loadAd(request); card_ads2.setVisibility(View.VISIBLE); adView2.loadAd(request2); if (snackbar != null) { snackbar.dismiss(); } progressBarLoadingRequests.setVisibility(View.INVISIBLE); if (fastItemAdapter.getAdapterItemCount() == 0) { emptyRVtext.setVisibility(View.VISIBLE); emptyRVtexthh.setVisibility(View.VISIBLE); card_ads2.setVisibility(View.INVISIBLE); } else { emptyRVtext.setVisibility(View.INVISIBLE); emptyRVtexthh.setVisibility(View.INVISIBLE); } // progressBarLoadingRequests.setVisibility(View.INVISIBLE); } @Override public void onCancelled(DatabaseError databaseError) { Snackbar snackbar = Snackbar .make(coordinatorLayout, databaseError.getMessage(), Snackbar.LENGTH_LONG); snackbar.setDuration(Snackbar.LENGTH_SHORT); snackbar.show(); // hRequestsLoadingDialog.dismiss(); progressBarLoadingRequests.setVisibility(View.INVISIBLE); } }); } @Override public void onKeyExited(String key) { } @Override public void onKeyMoved(String key, GeoLocation location) { } @Override public void onGeoQueryReady() { } @Override public void onGeoQueryError(DatabaseError error) { Toast.makeText(getBaseContext(), "Error retriving geoquery", Toast.LENGTH_SHORT).show(); } }); }Here's the error: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object referencePlease let me know how to retrieve only those posts which are within 0.5 kms of the user? 解决方案 Not knowing much about this I can't help much, however looking at your code this extract, from the GeoFire 2.0 page here, gives a good outline in javascript (rather than java) of what you're looking for. GeoFire’s real utility is shown by creating a GeoQuery. Say you are making an app for cyclists which shows the bicycle shops within a mile (1.609 kilometers) of a user’s current location. The first thing you need to do is add the bike shops you care about to GeoFire. Then, create a query centered at the user’s current location (let’s say they are at [37.4, -122.6]):var geoQuery = geoFire.query({ center: [37.4, -122.6], radius: 1.609 //kilometers}); A query on its own is not very useful. However, GeoFire allows you to add callback functions which are fired when important query events happen. Since you want to display every bike shop which matches the query criteria, listen for the key_entered event. Every time a key (that is, a bike shop) enters the query, the callback you defined will get called with data about that location:geoQuery.on("key_entered", function(key, location, distance) { console.log("Bicycle shop " + key + " found at " + location + " (" + distance + " km away)");}); It is important to realize that the key_entered event works like typical Firebase events. That is, it will be fired for every key in GeoFire which matches the query criteria, both keys which are already in GeoFire and those which are added at any point in the future. Thanks to Firebase, you receive these events in realtime. GeoFire is smart about how it looks for keys within the query. It does not need to load all of the GeoFire data into memory. If your user is looking for bicycle shops in San Francisco, GeoFire will not load data for locations in New York only to realize that they are on the opposite side of the country. It only checks on locations which are actually nearby. This keeps your app light and responsive, regardless of how big your data set is. If your user is biking around while looking for a shop to visit, it is possible that shops which were within a mile of them are now further away. To deal with this, GeoFire will fire the key_exited event for each key which leaves the query:geoQuery.on("key_exited", function(key, location, distance) { console.log("Bicycle shop " + key + " left query to " + location + " (" + distance + " km away)");}); That is really all you need to make your app work.The details available for Java appear to be sparser but for what you are trying to do this appears to be the thing:GeoQuery geoQuery = geoFire.queryAtLocation(currentUserLocation, 1.6);Reference here. 这篇关于如何检索我的范围内0.5公里内的帖子?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 10-11 00:16