添加或删除的Firebase Firestore上的重复RecyclerView项

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了添加或删除的Firebase Firestore上的重复RecyclerView项相关的知识,希望对你有一定的参考价值。

我正在使用Firebase firestore作为数据库构建一个应用程序,我添加了分页功能,但它的工作原理是,当从应用程序添加或删除数据时,回收项目重复出现,有时重复到3、4个位置,有时弄乱了安排。尝试寻找解决方案并最终覆盖了这些方法:

@Override
public long getItemId(int position) 
    return super.getItemId(position);


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

并且还要添加

setHasStableIds(true);

但仍然没有运气,这是我的代码片段:

public class HomeFragment extends Fragment 

private View view;
private LinearLayout mNoMedia;
private RecyclerView mMediaList;
private SwipeRefreshLayout mSwipe;
private TextView mNoInternet;

private FirebaseAuth mAuth;
private FirebaseFirestore firebaseFirestore;

private List<PostModel> postModelList;
private PostAdapter postAdapter;
private DocumentSnapshot lastVisible;
private Boolean isFirstPageFirstLoad;
private String currentUserId;
private final int NUM_COLUMNS = 2;
private StaggeredGridLayoutManager staggeredGridLayoutManager;

public HomeFragment() 
    // Required empty public constructor


@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) 
    // Inflate the layout for this fragment
    if (view == null) 
        view = inflater.inflate(R.layout.fragment_home, container, false);

        mAuth = FirebaseAuth.getInstance();
        firebaseFirestore = FirebaseFirestore.getInstance();

        mSwipe = view.findViewById(R.id.mainSwipe);
        mMediaList = view.findViewById(R.id.mediaList);
        mNoInternet = view.findViewById(R.id.no_internet);
        postModelList = new ArrayList<>();

        staggeredGridLayoutManager = new StaggeredGridLayoutManager(NUM_COLUMNS, StaggeredGridLayoutManager.VERTICAL);
        postAdapter = new PostAdapter(postModelList);
        postAdapter.setHasStableIds(true);

        mMediaList.setLayoutManager(staggeredGridLayoutManager);
        mMediaList.hasFixedSize();
        mMediaList.setHasFixedSize(true);
        mMediaList.setItemAnimator(null);
        mMediaList.setAdapter(postAdapter);

        mNoMedia = view.findViewById(R.id.mainMediaLin);

        //=========================== Functions ====================================================
        try 
            if (getActivity() != null) 
                if (mAuth.getCurrentUser() != null) 
                    currentUserId = mAuth.getCurrentUser().getUid();

                        loadPost();
                     else 
                        mNoMedia.setVisibility(View.VISIBLE);
                        mNoInternet.setVisibility(View.VISIBLE);
                    
                 else 
                    mNoMedia.setVisibility(View.VISIBLE);
                
            
         catch (Exception e) 
            e.printStackTrace();
        
    
    return view;


private void loadPost() 
    Query firstQuery = firebaseFirestore.collection("TubbePosts")
            .document(currentUserId).collection("Posts")
            .orderBy("utc", Query.Direction.DESCENDING).limit(8);
    firstQuery.addSnapshotListener(new EventListener<QuerySnapshot>() 
        @Override
        public void onEvent(@javax.annotation.Nullable QuerySnapshot queryDocumentSnapshots, @javax.annotation.Nullable FirebaseFirestoreException e) 
            if (queryDocumentSnapshots != null) 

                if (!queryDocumentSnapshots.isEmpty()) 
                    if (isFirstPageFirstLoad) 
                        lastVisible = queryDocumentSnapshots.getDocuments().get(queryDocumentSnapshots.size() - 1);
                        postModelList.clear();
                    
                    for (@NonNull DocumentChange doc : queryDocumentSnapshots.getDocumentChanges()) 
                        if (doc.getType() == DocumentChange.Type.ADDED) 

                            mNoMedia.setVisibility(View.GONE);
                            String docId = doc.getDocument().getId();
                            final PostModel postModel = doc.getDocument().toObject(PostModel.class).withId(docId);

                            if (isFirstPageFirstLoad) 
                                postModelList.add(postModel);
                             else 
                                postModelList.add(0, postModel);
                            
                            postAdapter.notifyDataSetChanged();

                        
                    

                    isFirstPageFirstLoad = false;
                
            
        
    );


public void loadMorePost() 

            Query nextQuery = firebaseFirestore.collection("TubbePosts")
                    .document(currentUserId).collection("Posts")
                    .orderBy("utc", Query.Direction.DESCENDING)
                    .startAfter(lastVisible).limit(8);
            nextQuery.addSnapshotListener(new EventListener<QuerySnapshot>() 
                @Override
                public void onEvent(@javax.annotation.Nullable QuerySnapshot queryDocumentSnapshots, @javax.annotation.Nullable FirebaseFirestoreException e) 
                    if (queryDocumentSnapshots != null) 
                        if (!queryDocumentSnapshots.isEmpty()) 
                            lastVisible = queryDocumentSnapshots.getDocuments().get(queryDocumentSnapshots.size() - 1);

                            for (@NonNull DocumentChange doc : queryDocumentSnapshots.getDocumentChanges()) 
                                if (doc.getType() == DocumentChange.Type.ADDED) 
                                    String docId = doc.getDocument().getId();
                                    @NonNull final PostModel postModel = doc.getDocument().toObject(PostModel.class).withId(docId);

                                    postModelList.add(postModel);
                                    postAdapter.notifyDataSetChanged();

                                
                            
                        
                    
                
            );


我的适配器:

public class PostAdapter extends RecyclerView.Adapter<PostAdapter.ViewHolder> 

private List<PostModel> postList;
private Context context;
private FirebaseFirestore firebaseFirestore;
private FirebaseAuth firebaseAuth;
private String img = null;
private RequestOptions placeholder;
private String userId, id;
private int ref;

public PostAdapter(List<PostModel> postList) 
    this.postList = postList;


@NonNull
@Override
public PostAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) 
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.post_item, parent, false);
    context = parent.getContext();
    firebaseFirestore = FirebaseFirestore.getInstance();
    firebaseAuth = FirebaseAuth.getInstance();
    return new PostAdapter.ViewHolder(view);


@Override
public void onBindViewHolder(@NonNull PostAdapter.ViewHolder holder, int position) 

    holder.setIsRecyclable(false);

    try 
        final String docId = postList.get(position).DocId;
        final String currentUserId = firebaseAuth.getCurrentUser().getUid();

        String postId = postList.get(position).getPostId();
        String posterId = postList.get(position).getPosterId();
        String descText = postList.get(position).getDescText();
        String mediaUrl = postList.get(position).getMediaUrl();
        String format = postList.get(position).getFormat();
        long utcTime = postList.get(position).getUtc().getTime();
        String utc = postList.get(position).getUtc().toString();

        if (format.equals("image")) 
            holder.setImg(mediaUrl);

         else if (format.equals("video")) 
            holder.mPlay.setVisibility(View.VISIBLE);
            holder.setVideoImg(mediaUrl);
        
        holder.mTime.setText(getTimeAgo(utcTime, context));
        holder.mDesc.setText(descText);

        firebaseFirestore.collection("TubbePosts").document(posterId)
                .collection("Posts")
                .document(postId).addSnapshotListener(new EventListener<DocumentSnapshot>() 
            @Override
            public void onEvent(@javax.annotation.Nullable DocumentSnapshot documentSnapshot, @javax.annotation.Nullable FirebaseFirestoreException e) 
                if (documentSnapshot != null) 
                    if (!documentSnapshot.exists()) 
                        try 
                            userId = currentUserId;
                            id = postId;
                            ref = position;

                            new DeleteProcess().execute();

                         catch (Exception f) 
                            f.printStackTrace();
                        
                    
                
            
        );

        firebaseFirestore.collection("Users").document(posterId)
                .addSnapshotListener(new EventListener<DocumentSnapshot>() 
                    @Override
                    public void onEvent(@javax.annotation.Nullable DocumentSnapshot documentSnapshot,
                                        @javax.annotation.Nullable FirebaseFirestoreException e) 
                        try 
                            if (documentSnapshot != null) 
                                if (documentSnapshot.exists()) 
                                    String image = documentSnapshot.getString("image");
                                    holder.setUserImg(image);
                                    img = image;
                                
                            

                         catch (Exception f) 
                            f.printStackTrace();
                        
                    
                );

        firebaseFirestore.collection("TubbePosts").document(posterId)
                .collection("Posts")
                .document(postId).collection("Likes")
                .addSnapshotListener(new EventListener<QuerySnapshot>() 
                    @Override
                    public void onEvent(@Nullable QuerySnapshot queryDocumentSnapshots, @Nullable FirebaseFirestoreException e) 
                        if (queryDocumentSnapshots != null) 
                            if (!queryDocumentSnapshots.isEmpty()) 
                                int count = queryDocumentSnapshots.size();
                                if (count < 1000) 
                                    holder.mLikeCount.setText(count + "");
                                 else 
                                    holder.mLikeCount.setText(getCount(count));
                                
                             else 
                                holder.mLikeCount.setText("0");
                            
                        
                    
                );

        firebaseFirestore.collection("TubbePosts").document(posterId)
                .collection("Posts").document(postId).collection("Likes")
                .document(currentUserId).addSnapshotListener(new EventListener<DocumentSnapshot>() 
            @Override
            public void onEvent(@Nullable DocumentSnapshot documentSnapshot, @Nullable FirebaseFirestoreException e) 
                if (documentSnapshot != null) 
                    if (documentSnapshot.exists()) 
                        holder.mLikeBtn.setImageDrawable(context.getResources().getDrawable(R.mipmap.heart_selected));
                     else 
                        holder.mLikeBtn.setImageDrawable(context.getResources().getDrawable(R.mipmap.heart));
                    
                
            
        );

        holder.mLikeBtn.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                if (isConnected(context)) 
                    firebaseFirestore.collection("TubbePosts")
                            .document(posterId)
                            .collection("Posts")
                            .document(postId).collection("Likes")
                            .document(currentUserId).get()
                            .addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() 
                                @Override
                                public void onComplete(@NonNull Task<DocumentSnapshot> task) 
                                    if (task.isSuccessful()) 
                                        if (task.getResult().exists()) 
                                            firebaseFirestore.collection("TubbePosts")
                                                    .document(posterId)
                                                    .collection("Posts")
                                                    .document(postId).collection("Likes")
                                                    .document(currentUserId).delete();
                                         else 
                                            Date utc = new Date(System.currentTimeMillis());
                                            Map<String, Object> likesMap = new HashMap<>();
                                            likesMap.put("utc", utc);

                                            firebaseFirestore.collection("TubbePosts")
                                                    .document(posterId)
                                                    .collection("Posts")
                                                    .document(postId).collection("Likes")
                                                    .document(currentUserId).set(likesMap);
                                        
                                    
                                
                            );

                
            
        );

        firebaseFirestore.collection("TubbePosts").document(posterId)
                .collection("Posts").document(postId).collection("Comments")
                .addSnapshotListener(new EventListener<QuerySnapshot>() 
                    @Override
                    public void onEvent(@Nullable QuerySnapshot queryDocumentSnapshots, @Nullable FirebaseFirestoreException e) 
                        if (queryDocumentSnapshots != null) 
                            if (!queryDocumentSnapshots.isEmpty()) 
                                int count = queryDocumentSnapshots.size();
                                if (count < 1000) 
                                    holder.mCommentCount.setText(count + "");
                                 else 
                                    holder.mCommentCount.setText(getCount(count));
                                
                             else 
                                holder.mCommentCount.setText("0");
                            
                        
                    
                );


        holder.mPosterImg.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                if (!currentUserId.equals(posterId)) 
                    Intent viewIntent = new Intent(context, ViewAccountActivity.class);
                    viewIntent.putExtra("userId", posterId);
                    context.startActivity(viewIntent);
                 else 
                    Toast.makeText(context, context.getResources().getString(R.string.your_account), Toast.LENGTH_SHORT).show();
                   /* AccountFragment accountFragment = new AccountFragment();
                    HomeFragment homeFragment = new HomeFragment();
                    FragmentTransaction fragmentTransaction = homeFragment.getActivity()
                            .getSupportFragmentManager()
                            .beginTransaction();
                    fragmentTransaction.replace(R.id.main_frame, accountFragment);
                    fragmentTransaction.addToBackStack(null);
                    fragmentTransaction.commit(); */
                
            
        );

        holder.mCommentBtn.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 

                Intent commentIntent = new Intent(context, CommentActivity.class);
                commentIntent.putExtra("posterId", posterId);
                commentIntent.putExtra("postId", postId);
                context.startActivity(commentIntent);
            
        );

        holder.mCard.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                Intent viewIntent = new Intent(context, ViewActivity.class);
                viewIntent.putExtra("postId", postId);
                viewIntent.putExtra("posterId", posterId);
                viewIntent.putExtra("desc", descText);
                viewIntent.putExtra("mediaUrl", mediaUrl);
                viewIntent.putExtra("posterImgUrl", img);
                viewIntent.putExtra("format", format);
                viewIntent.putExtra("utc", utc);
                context.startActivity(viewIntent);
            
        );

     catch (Exception e) 
        e.printStackTrace();
    


@Override
public int getItemCount() 
    return postList.size();


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


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


@Override
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) 
    super.onAttachedToRecyclerView(recyclerView);


public class ViewHolder extends RecyclerView.ViewHolder 

    private View mView;
    private CardView mCard;
    private ImageView mPostImage, mLikeBtn, mCommentBtn, mPosterImg, mPlay;
    private TextView mDesc, mLikeCount, mCommentCount, mTime;

    public ViewHolder(View itemView) 
        super(itemView);

        mView = itemView;
        mCard = mView.findViewById(R.id.postCard);
        mPostImage = mView.findViewById(R.id.post_img);
        mPosterImg = mView.findViewById(R.id.posterImg);
        mDesc = mView.findViewById(R.id.postDesc);
        mLikeBtn = mView.findViewById(R.id.likeBtn);
        mLikeCount = mView.findViewById(R.id.likesCount);
        mCommentBtn = mView.findViewById(R.id.commentBtn);
        mCommentCount = mView.findViewById(R.id.commentCount);
        mTime = mView.findViewById(R.id.postTime);
        mPlay = mView.findViewById(R.id.play_hint);
    

    private void setUserImg(String downloadUrl) 
        if (!TextUtils.isEmpty(downloadUrl)) 
            RequestOptions placeholderRequest = new RequestOptions();
            placeholderRequest.placeholder(R.color.grey200);
            Glide.with(context).setDefaultRequestOptions(placeholderRequest).load(downloadUrl).into(mPosterImg);
        
    

    private void setImg(String downloadUrl) 
        if (!TextUtils.isEmpty(downloadUrl)) 
            RequestOptions placeholderRequest = new RequestOptions();
            placeholderRequest.placeholder(R.drawable.ic_image);
            Glide.with(context).setDefaultRequestOptions(placeholderRequest).load(downloadUrl).into(mPostImage);
        
    

    private void setVideoImg(String downloadUrl) 
        if (!TextUtils.isEmpty(downloadUrl)) 
            long interval = getPosition() * 1000;
            RequestOptions options = new RequestOptions().frame(interval);
            placeholder = new RequestOptions();
            placeholder.placeholder(R.drawable.ic_image);
            Glide.with(context).setDefaultRequestOptions(placeholder).asBitmap()
                    .load(downloadUrl).apply(options).into(mPostImage);
        
    

和我的模特:

public class PostModel extends DocId 

private String descText, postId, mediaUrl, posterId, format;
private Date utc;

public PostModel ()

public PostModel(String descText, String postId, String mediaUrl, String posterId, String format, Date utc) 
    this.descText = descText;
    this.postId = postId;
    this.mediaUrl = mediaUrl;
    this.posterId = posterId;
    this.format = format;
    this.utc = utc;


public String getDescText() 
    return descText;


public String getPostId() 
    return postId;


public String getMediaUrl() 
    return mediaUrl;


public String getPosterId() 
    return posterId;


public String getFormat() 
    return format;


public Date getUtc() 
    return utc;

感谢您的帮助。

答案
productosLista.clear() for (doc in documentSnapshots!!) val producto = doc.toObject<Productos>(Productos::class.java) productosLista.add(producto)

以上是关于添加或删除的Firebase Firestore上的重复RecyclerView项的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Firebase 控制台从 Firestore 中删除索引?

在 pubspec.yaml 文件中添加 firebase_auth 或 cloud_firestore 时构建失败并出现异常(firebase_core 正在工作):

Firestore - 如何从值映射中添加/减去

Firebase Firestore。快照上的“成本”

如何在 Firebase Firestore 中获取内部集合

无法使用 SwiftUI 从 Firebase / Firestore 中删除文档