ios - Firebase - 跨多个位置的原子写入不起作用

标签 ios swift firebase swift3 firebase-realtime-database

如何使用此功能来更新 Firebase 中的实时数据库?我设法使该功能正常工作,但仅在触发 updateChild 时为帖子写入新的 ID。如何才能通过帖子 ID 更新当前帖子?

   var pathToPictures = [Pictures]()
   func updateAllImagesOfCurrentUserInDatabase() {

    //refrences
    let ref = FIRDatabase.database().reference()
    let uid = FIRAuth.auth()?.currentUser?.uid

    //match the user ID value stored into posts with current userID and get all the posts of the user
    let update = ref.child("posts").queryOrdered(byChild: "userID").queryEqual(toValue: uid)
    update.observe(FIRDataEventType.value, with: { (snapshot) in
           // print(snapshot)

        self.pathToPictures.removeAll()

        if snapshot.key != nil {

        let results = snapshot.value as! [String : AnyObject]

        for (_, value) in results {
            let pathToPostPicture = Pictures()

            if let pathToImage = value["pathToImage"] as? String , let postID = value["postID"] as? String {
                pathToPostPicture.postImageUrl = pathToImage
                pathToPostPicture.postID = postID
                self.pathToPictures.append(pathToPostPicture)
                print("Image and POST ID: \(pathToPostPicture.postImageUrl!)")
                print("Post ID is : \(postID)")

                if FIRAuth.auth()?.currentUser?.uid == uid {
                ref.child("Users_Details").child(uid!).child("profileImageUrl").observeSingleEvent(of: .value, with: { (userSnapshot) in
                    print(userSnapshot)

                    let userIMageUrl = userSnapshot.value as! String
                    pathToPostPicture.postImageUrl = userIMageUrl
                    self.pathToPictures.append(pathToPostPicture)
                    print("This is the image path:" + userIMageUrl + String(self.pathToPictures.count))

                    // Generate the path
                    let newPostRef = ref.child("posts").childByAutoId()
                    let newKey = newPostRef.key as String
                    print(newKey)
                    let updatedUserData = ["posts/\(postID)/pathToImage": pathToPostPicture.postImageUrl]
                    print("This is THE DATA:" , updatedUserData)
                    ref.updateChildValues(updatedUserData as Any as! [AnyHashable : Any])

                })

                }

                print(self.pathToPictures.count)

            }

            }
        } else {
            print("snapshot is nill")

        }

        self.collectionView?.reloadData()

    })
}

更新:这就是我的数据库的样子

这是我的数据库:

 "Users_Details" : {
    "aR0nRArjWVOhHbBFB8yUfao64z62" : {
      "profileImageUrl" : "url",
      "userID" : "aR0nRArjWVOhHbBFB8yUfao64z62"
    },
    "oGxXznrS2DS4ic1ejcSfKB5UlIQ2" : {
      "profileImageUrl" : "url",
      "userID" : "oGxXznrS2DS4ic1ejcSfKB5UlIQ2"
    }
  },
  "posts" : {
    "-KlzNLcofTgqJgfTaGN9" : {
      "fullName" : "full name",
      "interval" : 1.496785712879506E9,
      "normalDate" : "Tue, 06 Jun 2017 22:48",
      "pathToImage" : "url",
      "userID" : "oGxXznrS2DS4ic1ejcSfKB5UlIQ2"
    },
    "-KlzNXfvecIwBatXxmGW" : {
      "fullName" : "full name",
      "interval" : 1.496785761349721E9,
      "normalDate" : "Tue, 06 Jun 2017 22:49",
      "pathToImage" : "url",
      "userID" : "oGxXznrS2DS4ic1ejcSfKB5UlIQ2"
    },

让我告诉你它的作用:它循环遍历帖子并查找所有当前用户帖子。然后它获取每个帖子的图像 url 的路径并将其分配给一个数组。之后,它会查找图像 url 的当前用户路径,并用该路径更新整个数组。现在,我不知道如何使用新值更新数据库。如果有人知道,将不胜感激!

我希望在多个位置进行原子写入。有人可以告诉我如何修复我的代码来做到这一点吗?

它看起来像这样:

 // ATOMIC UPDATE HERE - IF SOMEBODY CAN FIND THE RIGHT WAY OF DOING THAT

                    // Generate a new push ID for the new post
                    let newPostRef = ref.child(byAppendingPath: "posts").childByAutoId()
                    let newPostKey = newPostRef.key
                    // Create the data we want to update
                    let updatedUserData = ["posts/\(newPostKey)": ["pathToImage": self.pathToPictures]] as [String : Any]

                    // Do a deep-path update
                    ref.updateChildValues(updatedUserData)

最佳答案

看来您将下载大量重复数据。虽然数据库非规范化是一种很好的做法,但我认为在这种情况下,最好不要在每个帖子中都包含相同的下载 URL。对于少数帖子来说并没有什么区别,但如果您有数千个用户和数万或数十万个帖子,则会下载大量额外数据。相反,您可以拥有一个包含 uids 作为键和配置文件 imageUrl 作为值的字典。您可以检查字典中是否有所需的 uid,如果不存在,则在数据库中查询该用户的 User_Details,然后将其添加到字典中。当你需要显示图像时,你可以从这个字典中获取 url。其他人可能对此有更好的建议,所以我欢迎其他想法。

如果您希望在每篇帖子中保留个人资料图片,那么我建议使用 Cloud Functions for Firebase。您可以创建一个函数,当用户的 User_Details 中更新 profileImageUrl 时,会更新其他帖子中的此条目。目前,Cloud Functions 仅在 Node.js 中可用。如果您不懂 JS,请不要让它成为一种阻碍!学习一点 JS 绝对是值得的。这些示例向您展示了入门所需了解的 JS 知识。 查看这些资源:

Getting Started with Cloud Functions for Firebase

GitHub samples

Cloud Functions for Firebase documentation

Writing a Database Trigger

Writing a Cloud Storage Trigger: Part 1

Writing a Cloud Storage Trigger: Part 2

关于ios - Firebase - 跨多个位置的原子写入不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44423881/

相关文章:

ios - Swift 钥匙串(keychain)和配置文件

node.js - 当存在子集合时,为什么从 Firestore 检索的数据返回空数组?

ios - IOS 应用程序中的 Firebase 云消息传递 (FCM) 无法正常工作

swift - UISlider 自定义拇指形状

objective-c - 你如何比较 Swift 中的 NSFontSymbolicTraits 和 NSFontBoldTrait?

javascript - Firestore .startAt 无法正常工作

ios - 无法从 appdelegate 推送 View Controller

ios - 在 View 出现后以编程方式更改 View

ios - XCUIElement isAccessibilityElement 返回为 false,即使该元素在 View 层次结构中报告为 Is Accessibility Element

ios - 如何从 nsdictionary 中获取选定值的键