将 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用户

有没有办法将 GeoFire 与 Firestore 一起使用?

Android geofire获取一定半径内的用户列表

GeoFire查询数据列表

GeoFire 查询完成 - Swift

用户位置的 GeoFire 查询