首页 > 解决方案 > 将 GeoFire 查询加载到 RecyclerView 时应用程序崩溃

问题描述

我正在开发一个基于位置的聊天应用程序作为最终任务,但是有一个我无法自己解决的错误。目前,我打算将某个半径内的所有配置文件加载到回收站视图中,并仅向当前用户显示这些配置文件。

回收站视图工作正常并显示我的 Firebase 数据库中的每个用户,直到我添加 GeoFire 查询以限制仅出现在 2 公里半径内的用户。所有用户的纬度和经度都已成功更新到数据库中,所以我认为这不是问题的根源。

当我运行应用程序并且它崩溃时,我在 LogCat 中得到了这个异常:

“java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法'double android.location.Location.getLatitude()'”

这让我很困惑,因为我数据库中的当前用户都没有为他们的经度或纬度存储空值。

所以我的主要问题是,我怎样才能只让当前用户 2 公里内的用户填充我的回收站视图,而不会导致应用程序崩溃?

数据库结构

当前源代码:

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();

}

我对编码还是很陌生,所以我非常感谢任何回复或帮助。谢谢!

安卓工作室 v3.1.3

标签: androidfirebasefirebase-realtime-databaseandroid-recyclerviewgeofire

解决方案


确保初始化mLastLocation. 我可以看到您正在从中检索 lat 和 lng 但从未初始化


推荐阅读