如何在OnClickListener中实现Firestore文档的校验与增删逻辑
解决方案:整合Firestore收藏的增删逻辑到单个点击事件
其实核心思路很清晰——先查询是否存在对应收藏文档,再根据结果执行删除或添加操作,把这些逻辑嵌套到同一个OnClickListener里就行。下面是整合后的完整代码,我会顺便解释关键步骤:
details_fave.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // 第一步:查询Favorites集合中是否存在当前用户+当前店铺的收藏 fStore.collection("Favorites") .whereEqualTo("usersID", UID) .whereEqualTo("shopID", SID) .get() .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() { @Override public void onComplete(@NonNull Task<QuerySnapshot> task) { if (task.isSuccessful()) { QuerySnapshot querySnapshot = task.getResult(); if (querySnapshot != null && !querySnapshot.isEmpty()) { // 情况1:存在收藏文档,执行删除操作 for (QueryDocumentSnapshot document : querySnapshot) { document.getReference().delete() .addOnSuccessListener(aVoid -> { Toast.makeText(DetailsActivity.this, "Removed from favorites", Toast.LENGTH_SHORT).show(); }) .addOnFailureListener(e -> { Toast.makeText(DetailsActivity.this, "Failed to remove favorite", Toast.LENGTH_SHORT).show(); }); } } else { // 情况2:不存在收藏文档,执行添加操作 Map<String, Object> fav = new HashMap<>(); fav.put("shopID", SID); fav.put("usersID", UID); fav.put("ShopHeaderImg", sHI); fav.put("ShopProfileImg", sPI); fav.put("address", sA); fav.put("costEst", sCost); fav.put("country", sC); fav.put("latitude", sLat); fav.put("location", sL); fav.put("name", sN); fav.put("numTables", sNumTable); fav.put("ratings", sR); fav.put("summary", sSummary); fav.put("timing", sT); fStore.collection("Favorites").add(fav) .addOnSuccessListener(documentReference -> { Toast.makeText(DetailsActivity.this, "Saved to favorites", Toast.LENGTH_SHORT).show(); }) .addOnFailureListener(e -> { Toast.makeText(DetailsActivity.this, "Something went wrong", Toast.LENGTH_SHORT).show(); }); } } else { // 查询失败的处理 Log.d("Favorites", "Error checking favorite status: ", task.getException()); Toast.makeText(DetailsActivity.this, "Failed to check favorite status", Toast.LENGTH_SHORT).show(); } } }); } });
关键细节说明:
- 查询优先级:点击事件触发后,先执行Firestore的查询操作,这是异步的,所以所有后续逻辑都要放在
onComplete回调里,确保拿到查询结果再做判断。 - 空结果判断:通过
querySnapshot.isEmpty()来判断是否存在目标文档——为空说明没有收藏,反之则有。 - 删除操作的遍历:虽然按业务逻辑,同一个用户+店铺应该只有一条收藏,但遍历所有匹配文档是更稳妥的做法,避免因意外重复数据导致的问题。
- Toast提示区分:把原来的统一"Saved"改成了区分添加/删除的提示,提升用户体验。
另外,额外提个优化点:你可以考虑用复合文档ID(比如UID + "_" + SID)来替代自动生成的文档ID,这样可以直接通过document(复合ID).get()来查询,效率更高,还能从根源避免重复收藏的问题。如果用这种方式,删除的时候也不需要遍历,直接删除对应ID的文档就行。
内容的提问来源于stack exchange,提问作者user14054849
相关产品推荐
相关产品推荐

