You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firebase Firestore:如何判断用户ID是否已存在于数组中并移除,及类Twitter点赞功能的结构优化问询

Evaluating Like Feature Implementations for Your Twitter-like App

Let’s break down your current approach and compare it to the subcollection alternative to help you make the right choice.

First: Your Current Implementation Is Incorrect

The code you’re using overwrites the entire likes document every time a user likes a tweet:

let _ = try await db.collection("likes")
    .document(like.tweetDocumentId)
    .setData([
        "tweetDocumentId": like.tweetDocumentId,
        "userIds": [like.userId]
    ])

This means if another user already liked the tweet, their ID will be replaced with the current user’s ID—definitely not what you want. For adding likes correctly with the array approach, you should use arrayUnion to append the user ID without overwriting existing entries:

try await db.collection("likes")
    .document(like.tweetDocumentId)
    .updateData([
        "userIds": FieldValue.arrayUnion([like.userId])
    ])

And for unliking, use arrayRemove:

try await db.collection("likes")
    .document(like.tweetDocumentId)
    .updateData([
        "userIds": FieldValue.arrayRemove([like.userId])
    ])

Even with this fix, the array approach has critical limitations to consider.

Comparing Array vs. Subcollection Approaches

1. Array-Based Approach (Your Current Structure)

Pros:

  • Simple to implement for small-scale apps
  • Easy to get the total like count (just fetch the array length)
  • Single write operation per like/unlike

Cons:

  • Document size limit: Firestore documents max out at 1MB. If a tweet gets thousands of likes (each user ID is ~20 characters), you’ll hit this limit quickly (roughly 50k likes per tweet).
  • Inefficient user-like checks: To verify if a user liked a tweet, you have to fetch the entire array—slow and wasteful if the array is large.

2. Subcollection-Based Approach (likes/{TweetID}/users/{UserId})

Pros:

  • Unlimited scalability: No document size limits, so even viral tweets with millions of likes are handled easily.
  • Efficient user-like checks: To see if a user liked a tweet, just check if the document likes/{TweetID}/users/{UserId} exists—this is a fast, single-document read.
  • Straightforward deletion: Unliking is as simple as deleting the user’s document in the subcollection.

Cons:

  • Like count requires extra work: You’ll need to use Firestore’s count() aggregation (efficient and server-side) or maintain a separate counter document to track total likes.
  • Slightly more setup: You’ll need to manage subcollection documents instead of a single array, but this is minimal overhead.

Does Using Subcollections Hurt Performance?

No—Firestore is designed to handle millions of subcollections without performance issues. Subcollections are just part of the document path; there’s no extra overhead for creating one per tweet. Reads/writes on subcollection documents perform exactly the same as any other Firestore document.

Recommendation

  • If your app is small-scale and you don’t expect tweets to get thousands of likes: Stick with the array approach (fixed with arrayUnion/arrayRemove).
  • If you want scalability (like Twitter-level traffic) or need efficient user-like checks: Go with the subcollection approach. It’s more future-proof and avoids the array’s limitations.

内容的提问来源于stack exchange,提问作者Mary Doe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 19:27:28