【问题标题】:SwiftUI Firebase - Remembering VariableSwiftUI Firebase - 记住变量
【发布时间】:2021-09-10 09:57:01
【问题描述】:

在我的应用程序中,我试图阻止用户点赞帖子两次。我当前的代码是:

@State private var isLiked = false
HStack {
                Button(action: {if isLiked == false{
                    postData.addLike(id: post.id)
                    isLiked = true
                } else{
                    postData.unLike(id: post.id)
                    isLiked = false
                }}, label: {
                    Image(systemName: isLiked ? "heart.fill" : "heart")
                        .resizable()
                        .aspectRatio(contentMode: .fill)
                        .frame(width: 20)
                        .foregroundColor(isLiked ? .red : .gray)

目前,当第一次按下like按钮时,它会变成红色并执行“addLike”。但是,如果我关闭应用程序并重新打开它,按钮不再是红色的。无论应用程序关闭/重新打开多少次,我都希望按钮保持红色,直到用户按下它以不同于它。

我已经阅读了有关使用 UserDefaults 的信息,但这些在卸载应用程序时会被清除。我有我的应用程序链接到 Google Firebase,所以我想当应用程序被喜欢时,将用户 ID 添加到名为“likedBy”的列中?然后,当应用程序打开时,让应用程序扫描用户 ID 以查看该帖子是否已被他们喜欢。我不知道如何实现这一点。

对不起,如果这是一个愚蠢的问题,我制作这个应用程序是为了好玩和学习。

编辑 由于我在下面标记的答案,我已经能够部分解决这个问题。我在后端(postData)中设置了一个数组:

self.ref.collection("Posts").document(id).updateData([
                "likedBy": FieldValue.arrayUnion([self.uid])
self.ref.collection("Posts").document(id).updateData([
                "likedBy": FieldValue.arrayRemove([self.uid])

此代码将用户的 UID 设置到 likeBy 数组中。现在,我需要弄清楚如何读取这些数据,然后查看用户的 UID 是否等于在数组中找到的 UID。

我的新问题: SwiftUI Firebase - Reading Array Data to see if string is equal to an array string

【问题讨论】:

  • 您使用的是 Firestore 还是实时数据库?每个人都没有真正的“列”,但听起来你在用户喜欢某个项目时存储用户 ID 是正确的。然后,您必须在应用程序/视图启动时读取该数据,并在用户“喜欢”或“不喜欢”该项目时更新它。
  • 不特定于 SwiftUI 部分,但这些是否回答了您关于在 Firestore 中实现“喜欢”功能的问题? stackoverflow.com/questions/60441035/…stackoverflow.com/questions/48300034/…
  • 我正在使用 Firestore。不知道为什么我说“列”。

标签: ios swift xcode firebase swiftui


【解决方案1】:

你有两种方法来处理这个问题,这两种方法都需要你考虑所有可能的情况。选项 #1,您仅通过 Firebase 处理它。选项 #2,您在本地处理它并推送到 Firebase。您已经提到了选项 #2 的一个问题,即卸载会导致它丢失数据。显而易见的最佳解决方案是选项 #1,我们让 Firebase 处理它。

选项#1的实现

让我们从逻辑上考虑这个问题,用户喜欢一个项目,firebase 更新为对该“帖子 ID”的“引用”(我假设)。如果应用关闭并重新打开,则没有数据表明帖子被点赞。

要解决这个问题,我们需要添加一个检查以获取已保存到 firebase 的数据。如果数据存在,则将其设置为“喜欢”,如果不将其设置为“默认”

在您的 Firebase 中,您可能需要这样的文档结构。

user/profiles/<someProfileId>/likedPosts : [ someID, someID2, someID3 ] 

每次应用启动时,firebase 都会在运行时检查此特定文档并获取相关字典。这样做的目的是#1,它是简单的数据抓取,#2 它可以防止不必要的 Firebase 查询。然后,您需要将其存储在某个对象中。我推荐一个单例,因为你会在所有地方都需要这些数据。它可能看起来像这样。

class FirebaseDataManager {
     static var shared = FirebaseDataManager()
     var likedPosts: [String] //String or Int ID's to the posts themselves.      

     init() {
          //Fetch our latest liked posts
          super.init()
          likedPosts = fetchRecentLikedPosts()
     }
  
     func fetchRecentLikedPosts() -> [String] {
          //Do whatever logic you need to here. 
          return [String]()
     }

     func addLikedPost(postID: String) {
          //Add to the likedPosts [String] & Firebase
     }
}

这样做可以让您拥有作为 Firebase 的“事实来源”,从而消除您在数据不同步或不断查询 Firebase 时可能遇到的任何问题。要启动,您可以从任何地方访问它。进一步深入研究,每次显示帖子时,对照FirebaseDataManager.shared.likedPosts 数组检查 ID,如果匹配,您就知道它是喜欢的,相应地设置。

使用示例

struct someView: View {
  
    let firManager = FirebaseDataManager.shared

    var body: some View { 
        //You should handle the case when there is nothing. 
        //This is merely an example. 
        Text("\(firManager.likedPosts.first())"
    }

}

文档:https://firebase.google.com/docs/firestore/query-data/get-data

我鼓励您查看有关我在这里提到的一些概念的 firebase 文档。他们的文档将极大地帮助您。如果您有任何问题,请告诉我,我会尽力帮助您。

【讨论】:

  • 正如你所说,我认为最好的选择是选项#1。当用户喜欢一个项目时,“喜欢”会加一。 Firebase 中的点赞位于 Posts/(post id)/likes。喜欢只是一个增加的数字。据我了解,您是说在我的“用户/(用户)”集合中创建一个新部分(我称之为用户而不是个人资料)并在该部分中包含用户喜欢的每个帖子 ID?我正在考虑这样做,但是我不知道如何在一个部分中添加更多 ID。我知道如何将 [someID] 添加到字符串,但我不知道如何将其他 [someID2, 3] 添加到同一字符串。
  • 另外,init() { likedPosts = fetchRecentLikedPosts() } 我收到错误“self used in method call fetchRecentLikedPosts before stored all properties are initialized”
  • 忘了你必须打电话给super.init()
  • 使用 Firebase 的 .UpdateValue([String:Any]) 在文档本身上创建字典。不要使用字符串。所以你可能有这样的价值。 ["likedPosts" : [ "post1", "post2" ] Firebase 会自动判断Any 的类型并放入适当的位置。
猜你喜欢
  • 2023-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-16
  • 1970-01-01
  • 1970-01-01
  • 2020-08-26
  • 1970-01-01
相关资源
最近更新 更多