尝试在空对象引用上调用虚拟方法'boolean com.google.firebase.firestore.QuerySnapshot.isEmpty()'

时间:2019-02-13 17:45:57

标签: android firebase nullpointerexception google-cloud-firestore

我正在构建一个博客应用,用户可以在其中发布带有说明的图像。对于数据库,我正在使用 firebase firestore 。一切正常,除了一件事。

用户从其帐户注销时,会抛出 空指针 ,并说 试图调用虚拟方法'boolean com.google.firebase空对象引用上的.firestore.QuerySnapshot.isEmpty()” ,当用户注销2-3秒后,应用立即崩溃。

在logcat中,它说适配器类的错误和行号是101104。

BlogRecyclerAdapter.java

package com.naimsplanet.photoblog;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.text.format.DateFormat;
import android.text.style.IconMarginSpan;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.EventListener;
import com.google.firebase.firestore.FieldValue;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.FirebaseFirestoreException;
import com.google.firebase.firestore.QuerySnapshot;


//import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import de.hdodenhof.circleimageview.CircleImageView;

public class BlogRecyclerAdapter extends RecyclerView.Adapter<BlogRecyclerAdapter.ViewHolder> {

    public List<Blog> blog_list;
    public Context context;
    private FirebaseFirestore firebaseFirestore;
    private FirebaseAuth mAuth;

    public BlogRecyclerAdapter(List<Blog> blog_list) {
        this.blog_list = blog_list;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.blog_list_item, parent, false);
        context = parent.getContext();
        firebaseFirestore = FirebaseFirestore.getInstance();
        mAuth = FirebaseAuth.getInstance();
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {

        holder.setIsRecyclable(false);

        final String blogPostId = blog_list.get(position).BlogPostId;
        final String currentUserId = mAuth.getCurrentUser().getUid();
        String description_data = blog_list.get(position).getDesc();
        holder.setDescriptionText(description_data);
        String blog_post_image = blog_list.get(position).getImage_url();
        String blog_post_thumb = blog_list.get(position).getImage_url();
        holder.setBlogImage(blog_post_image, blog_post_thumb);

        String user_id = blog_list.get(position).getUser_id();
        firebaseFirestore.collection("Users").document(user_id).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
            @Override
            public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                if (task.isSuccessful()) {
                    String username = task.getResult().getString("name");
                    String userimage = task.getResult().getString("image");

                    holder.setUserData(username, userimage);
                } else {

                }
            }
        });

        try {
            long millisecond = blog_list.get(position).getTimestamp().getTime();
            String dateString = DateFormat.format("MM/dd/yyyy", new Date(millisecond)).toString();
            holder.setTime(dateString);
        } catch (Exception e) {

            Toast.makeText(context, "Exception : " + e.getMessage(), Toast.LENGTH_SHORT).show();

        }

        //get like count
        firebaseFirestore.collection("Posts/" + blogPostId + "/Likes").addSnapshotListener((Activity) context, new EventListener<QuerySnapshot>() {
            @Override
            public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {
                if (!documentSnapshots.isEmpty()) {
                    int count = documentSnapshots.size();
                    holder.updateLikeCount(count);

                } else {
                    holder.updateLikeCount(0);
                }
            }
        });

        //get likes

        firebaseFirestore.collection("Posts/" + blogPostId + "/Likes").document(currentUserId).addSnapshotListener((Activity) context, new EventListener<DocumentSnapshot>() {
            @Override
            public void onEvent(DocumentSnapshot documentSnapshot, FirebaseFirestoreException e) {
                if (documentSnapshot.exists()) {
                    holder.blogLikeButton.setImageDrawable(context.getDrawable(R.mipmap.like_button_accent));
                    //Log.e("MyTag", "Firebase exception", e);
                } else {
                    holder.blogLikeButton.setImageDrawable(context.getDrawable(R.mipmap.like_button_gray));
                    //Log.e("MyTag", e.toString());
                }
            }
        });


        //blog like button
        holder.blogLikeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                firebaseFirestore.collection("Posts/" + blogPostId + "/Likes").document(currentUserId).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
                    @Override
                    public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                        if (!task.getResult().exists()) {
                            Map<String, Object> likeMap = new HashMap<>();
                            likeMap.put("timeStamp", FieldValue.serverTimestamp());
                            firebaseFirestore.collection("Posts/" + blogPostId + "/Likes").document(currentUserId).set(likeMap);

                        } else {
                            firebaseFirestore.collection("Posts/" + blogPostId + "/Likes").document(currentUserId).delete();
                        }
                    }
                });

            }
        });

        holder.blogCommnetButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent commentIntent = new Intent(context, CommentActivity.class);
                commentIntent.putExtra("blog_post_id", blogPostId);
                context.startActivity(commentIntent);
            }
        });
    }

    @Override
    public int getItemCount() {
        return blog_list.size();
    }

    @Override
    public int getItemViewType(int position) {
        return position;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        private View mView;
        private TextView descriptionView;
        private ImageView blogImage;
        private TextView blogDate;
        private TextView userName;
        private CircleImageView userImage;
        private ImageView blogLikeButton;
        private TextView blogLikeCounter;
        private ImageView blogCommnetButton;

        public ViewHolder(View itemView) {
            super(itemView);
            mView = itemView;

            blogLikeButton = mView.findViewById(R.id.blog_like_button);
            blogCommnetButton = mView.findViewById(R.id.comment_btn);
        }

        public void setDescriptionText(String desc) {
            descriptionView = mView.findViewById(R.id.blog_desc);
            descriptionView.setText(desc);
        }

        public void setBlogImage(String downloadUrl, String thumbUrl) {
            blogImage = mView.findViewById(R.id.blog_image);
            RequestOptions requestOptions = new RequestOptions();
            requestOptions.placeholder(R.drawable.image_placeholder);
            Glide.with(context).applyDefaultRequestOptions(requestOptions).load(downloadUrl).thumbnail(
                    Glide.with(context).load(thumbUrl)
            ).into(blogImage);
        }

        public void setTime(String date) {
            blogDate = mView.findViewById(R.id.blog_date);
            blogDate.setText(date);
        }

        private void setUserData(String name, String image) {
            userName = mView.findViewById(R.id.blog_user_name);
            userImage = mView.findViewById(R.id.blog_user_image);
            userName.setText(name);
            RequestOptions placeHolder = new RequestOptions();
            placeHolder.placeholder(R.drawable.profile_placeholder);
            Glide.with(context).applyDefaultRequestOptions(placeHolder).load(image).into(userImage);
        }

        public void updateLikeCount(int count) {
            blogLikeCounter = mView.findViewById(R.id.blog_like_count);
            blogLikeCounter.setText(count + " Likes");
        }


    }
}

HomeFragment.class

package com.naimsplanet.photoblog;


import android.app.Dialog;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.support.v4.app.Fragment;
import android.widget.Toast;

import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.firestore.DocumentChange;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.EventListener;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.FirebaseFirestoreException;
import com.google.firebase.firestore.Query;
import com.google.firebase.firestore.QuerySnapshot;

import java.util.ArrayList;
import java.util.List;

/**
 * A simple {@link Fragment} subclass.
 */
public class HomeFragment extends Fragment {

    private RecyclerView mBlog_list_view;
    private List<Blog> blog_list;
    private FirebaseFirestore firebaseFirestore;
    private BlogRecyclerAdapter blogRecyclerAdapter;
    private FirebaseAuth mAuth;
    private DocumentSnapshot lastVisible;
    private Boolean isFirtPageFirstLoad = true;

    public HomeFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_home, container, false);

        blog_list = new ArrayList<>();
        mBlog_list_view = view.findViewById(R.id.blog_list_view);
        blogRecyclerAdapter = new BlogRecyclerAdapter(blog_list);
        mBlog_list_view.setLayoutManager(new LinearLayoutManager(container.getContext()));
        mBlog_list_view.setAdapter(blogRecyclerAdapter);
        mBlog_list_view.setHasFixedSize(true);
        mAuth = FirebaseAuth.getInstance();


        if (mAuth.getCurrentUser() != null ) {
            firebaseFirestore = FirebaseFirestore.getInstance();
            mBlog_list_view.addOnScrollListener(new RecyclerView.OnScrollListener() {
                @Override
                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    super.onScrolled(recyclerView, dx, dy);
                    Boolean bottomPost = !recyclerView.canScrollVertically(1);

                    if (bottomPost) {
                        loadMorePost();
                    }
                }
            });
            Query firstQuery = firebaseFirestore.collection("Posts").
                    orderBy("timestamp", Query.Direction.DESCENDING)
                    .limit(3);

            firstQuery.addSnapshotListener(getActivity(), new EventListener<QuerySnapshot>() {
                @Override
                public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {
                    if (documentSnapshots != null) {

                        if (isFirtPageFirstLoad) {
                            lastVisible = documentSnapshots.getDocuments().get(documentSnapshots.size()-1);
                            blog_list.clear();
                        }

                        for (DocumentChange doc : documentSnapshots.getDocumentChanges()) {
                            if (doc.getType() == DocumentChange.Type.ADDED) {
                                String blogPostId = doc.getDocument().getId();
                                Blog blog = doc.getDocument().toObject(Blog.class).withID(blogPostId);
                                if (isFirtPageFirstLoad) {
                                    blog_list.add(blog);
                                } else {
                                    blog_list.add(0, blog);
                                }

                                blogRecyclerAdapter.notifyDataSetChanged();
                            }
                        }

                        isFirtPageFirstLoad = false;
                    }
                }
            });
        }

        return view;
    }

    private void loadMorePost() {

        if (mAuth.getCurrentUser() != null) {
            Query nextQuery = firebaseFirestore.collection("Posts")
                    .orderBy("timestamp", Query.Direction.DESCENDING)
                    .startAfter(lastVisible)
                    .limit(3);

            nextQuery.addSnapshotListener(getActivity(), new EventListener<QuerySnapshot>() {
                @Override
                public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {

                    if (!documentSnapshots.isEmpty()) {
                        lastVisible = documentSnapshots.getDocuments().get(documentSnapshots.size() - 1);
                        for (DocumentChange doc : documentSnapshots.getDocumentChanges()) {
                            if (doc.getType() == DocumentChange.Type.ADDED) {
                                String blogPostId = doc.getDocument().getId();
                                Blog blog = doc.getDocument().toObject(Blog.class).withID(blogPostId);
                                blog_list.add(blog);
                                blogRecyclerAdapter.notifyDataSetChanged();
                            }
                        }
                    }
                }
            });
        }
    }


}

模型类(Blog.class):

package com.naimsplanet.photoblog;


import java.util.Date;

public class Blog extends BlogPostId {
    private String image_url;
    private String desc;
    private String user_id;
    private String thumb_image;
    private Date timestamp;


    public Blog() {

    }

    public Blog(String image_url, String desc, String user_id, String thumb_image, Date timestamp) {
        this.image_url = image_url;
        this.desc = desc;
        this.user_id = user_id;
        this.thumb_image = thumb_image;
        this.timestamp = timestamp;

    }

    public Date getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(Date timestamp) {
        this.timestamp = timestamp;
    }

    public String getImage_url() {
        return image_url;
    }

    public void setImage_url(String image_url) {
        this.image_url = image_url;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public String getUser_id() {
        return user_id;
    }

    public void setUser_id(String user_id) {
        this.user_id = user_id;
    }

    public String getThumb_image() {
        return thumb_image;
    }

    public void setThumb_image(String thumb_image) {
        this.thumb_image = thumb_image;
    }


}

2 个答案:

答案 0 :(得分:1)

在查询侦听器回调中:

        public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {
            if (!documentSnapshots.isEmpty()) {
                int count = documentSnapshots.size();
                holder.updateLikeCount(count);

            } else {
                holder.updateLikeCount(0);
            }
        }
如果出现错误,

documentSnapshots将为null。错误消息将在给定的FirebaseFirestoreException对象内。回调将始终以快照主机或异常的形式传递,永远不会同时传递,也永远不会传递。您应该同时检查两者。

答案 1 :(得分:0)

我在@Doug Stevenson的回复中解决了该错误。

我所做的是,在出现空指针异常的地方,我只用了以下代码:

if(e == null) 

就像我更改了下面的代码

public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {
                if (!documentSnapshots.isEmpty()) {
                    int count = documentSnapshots.size();
                    holder.updateLikeCount(count);

                } else {
                    holder.updateLikeCount(0);
                }
            }

带有以下提示:

public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {
                if (e == null) {
                    if (!documentSnapshots.isEmpty()) {
                        int count = documentSnapshots.size();
                        holder.updateLikeCount(count);

                    } else {
                        holder.updateLikeCount(0);
                    }
                }
            }

这帮助我停止获取空指针异常。