如何使此功能更新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)
答案 0 :(得分:0)
看起来您将要下载大量重复数据。虽然数据库的非规范化是一种很好的做法,但我认为在这种情况下,您最好不要在每个帖子中包含相同的下载URL。它并不会对少数帖子产生影响,但如果您有数千名用户以及数十或数十万个帖子,则会下载大量额外数据。相反,您可以使用包含uids作为键的字典,并将配置文件imageUrl作为值。您可以检查所需的uid的字典,如果它不存在,则查询该用户的User_Details
数据库,然后将它们添加到字典中。当您需要显示图像时,您将从此词典中获取网址。其他人可能会有更好的建议,所以我欢迎其他想法。
如果您希望在每个帖子中保留个人资料图片,那么我建议您使用Cloud Functions for Firebase。您可以创建一个功能,在用户profileImageUrl
中更新User_Details
后,在其他帖子中更新此条目。目前,云功能仅在Node.js中可用。如果你不了解JS,请不要让它成为威慑!学习一点JS绝对值得。这些示例向您展示了与您开始时必须知道的JS一样多的JS。
查看这些资源:
Getting Started with Cloud Functions for Firebase
Cloud Functions for Firebase documentation
答案 1 :(得分:0)
经过几天的逻辑挣扎后,我终于明白了。如果有人会遇到这样的事情,这就是答案。在我的情况下,它是关于在用户更改其图像时更新当前用户的所有帖子(我的帖子使用非规范化,因此每个图像路径都不同)。它将遍历帖子,找到与其UserID匹配的当前用户postsID,将它们放入数组中,找到currentUser图片并使用图像路径更新该数组。最后将更新Firebase数据库!
var addButtons = function() {
var wrapper = document.getElementsByClassName("wrapper")[0];
var num, node;
for (var i = 0; i < 10; i++) {
console.info("Button"+i);
num = document.createElement("div");
num.className = "number";
node = document.createTextNode(i);
num.appendChild(node);
wrapper.appendChild(num);
}
}
addButtons();