将 GeoFire 查询加载到 RecyclerView 时应用程序崩溃
Posted
技术标签:
【中文标题】将 GeoFire 查询加载到 RecyclerView 时应用程序崩溃【英文标题】:Application crashes when loading a GeoFire query into RecyclerView 【发布时间】:2019-01-30 09:50:51 【问题描述】:我正在开发一个基于位置的聊天应用程序作为最终任务,但是有一个我无法自己解决的错误。目前,我打算将某个半径内的所有配置文件加载到回收站视图中,并仅向当前用户显示这些配置文件。
回收器视图工作正常,并显示我的 Firebase 数据库中的每个用户,直到我添加 GeoFire 查询以限制仅出现在 2 公里半径内的用户。所有用户的经纬度都已成功更新到数据库中,所以我认为这不是问题的根源。
当我运行应用程序并且它崩溃时,我在 LogCat 中得到这个异常:
“java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法'double android.location.Location.getLatitude()'”
这让我很困惑,因为我数据库中的当前用户都没有为他们的经度或纬度存储空值。
所以我的主要问题是,我怎样才能只让当前用户 2 公里以内的用户填充我的回收站视图,而不会导致应用程序崩溃?
Database structure
当前源码:
public class FindChatters extends Fragment
private RecyclerView mUsersList;
private View mMainView;
private DatabaseReference mUsersDatabase;
private FirebaseUser mCurrentUser;
private LatLng myCurrentLocation;
private String mUserFound;
private static final int RADIUS = 2;
Location mLastLocation;
public FindChatters()
// Required empty public constructor
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
// Inflate the layout for this fragment
mMainView = inflater.inflate(R.layout.fragment_find_chatters, container, false);
mUsersDatabase = FirebaseDatabase.getInstance().getReference().child("Users");
mCurrentUser = FirebaseAuth.getInstance().getCurrentUser();
mUsersList = (RecyclerView) mMainView.findViewById(R.id.users_list);
mUsersList.setHasFixedSize(true);
mUsersList.setLayoutManager(new LinearLayoutManager(getContext()));
return mMainView;
//RETRIEVE DATA IN REALTIME
@Override
public void onStart()
super.onStart();
startListening();
public void startListening()
Query query = FirebaseDatabase.getInstance().getReference().child("Users").limitToLast(50);
FirebaseRecyclerOptions<Users> options = new FirebaseRecyclerOptions.Builder<Users>().setQuery(query, Users.class).build();
FirebaseRecyclerAdapter adapter = new FirebaseRecyclerAdapter<Users, UserViewHolder>(options)
@Override
public UserViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
// CREATE NEW INSTANCE OF VIEWHOLDER, USING CUSTOM LAYOUT (R.LAYOUT.MESSAGE)
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.users_single_layout, parent, false);
return new UserViewHolder(view);
@Override
protected void onBindViewHolder(final UserViewHolder holder, final int position, final Users model)
// // //
//RETRIEVE CURRENT USERS LAT/LONG TO FIND USERS NEARBY
String userID = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference myLoc = FirebaseDatabase.getInstance().getReference().child("Geo");
final GeoFire geoFire = new GeoFire(myLoc);
geoFire.setLocation(userID, new GeoLocation(mLastLocation.getLatitude(), mLastLocation.getLongitude()));
myCurrentLocation = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());
//RETRIEVE USERS ONLY FROM WITHIN A SPECIFIED RADIUS TO THE CURRENT USER
DatabaseReference findNearby = FirebaseDatabase.getInstance().getReference().child("Geo");
GeoFire geoFire2 = new GeoFire(findNearby);
//QUERY ALL NEARBY USERS IN THE DATABASE WITHIN 2KM OF CURRENT USER LAT/LONG
final GeoQuery geoQuery = geoFire2.queryAtLocation(new GeoLocation(myCurrentLocation.latitude, myCurrentLocation.longitude), RADIUS);
//QUERY TO RETRIEVE CLOSET USERS
geoQuery.addGeoQueryEventListener(new GeoQueryEventListener()
//IF ANY USERS FOUND WITHIN RADIUS - ON KEY ENTERED IS CALLED
@Override
public void onKeyEntered(String key, GeoLocation location)
if (geoQuery != null)
mUserFound = key;
//BIND CHAT OBJECT TO CHATHOLDER
holder.setName(model.name);
holder.setUserStatus(model.status);
holder.setUserOnline(model.online);
holder.setUserImage(getContext(), model.image);
//CLICK ON A USER PROFILE TO ACCESS THEIR INFORMATION OR INITIATE CHAT
final String user_id = getRef(position).getKey();
//RETRIEVE CURRENT USER ID
String current_uid = mCurrentUser.getUid();
//PREVENT USER FROM BEING ABLE TO INITIATE A CONVERSATION WITH THEMSELF
if (!user_id.equals(current_uid))
holder.mView.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
Intent profileIntent = new Intent(getActivity(), ProfileActivity.class);
profileIntent.putExtra("user_id", user_id);
startActivity(profileIntent);
);
else
holder.setName("You");
holder.setUserStatus("Tap someone to say hello!");
else
//CREATE TEXTVIEW TO INFORM USER THAT NO NEARBY USERS ARE PRESENT
@Override
public void onKeyExited(String key)
@Override
public void onKeyMoved(String key, GeoLocation location)
@Override
public void onGeoQueryReady()
@Override
public void onGeoQueryError(DatabaseError error)
);
// // //
;
mUsersList.setAdapter(adapter);
adapter.startListening();
我对编码还是很陌生,所以我非常感谢任何回复或帮助。谢谢!
android Studio v3.1.3
【问题讨论】:
mLastLocation
从未初始化因此问题
谢谢,如果代码在初始化后可以正常工作,我会发布。
【参考方案1】:
确保初始化mLastLocation
。我可以看到您正在从中检索 lat 和 lng,但从未初始化
【讨论】:
啊,谢谢,我会在我初始化代码后回复代码是否成功。以上是关于将 GeoFire 查询加载到 RecyclerView 时应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章
如何使用geofire查询检查10公里半径内是不是存在firebase用户