我正在构建一个博客应用,用户可以在其中发布带有说明的图像。对于数据库,我正在使用 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;
}
}
答案 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);
}
}
}
这帮助我停止获取空指针异常。