2017-06-07 1 views
0

この機能をFirebaseのリアルタイムデータベースを更新するにはどうすればよいですか?私はその機能を働かせるように管理しましたが、updateChildがトリガされたときに投稿用の新しいIDを書くだけでした。投稿IDで現在の投稿を更新するにはどうすればよいですか?Firebase - 複数の場所にわたるアトミック書き込みが動作しない

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() 

    }) 
} 

UPDATE:

"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

@JenPersonはい、これは私が達成したいことです。私は自分の質問をデータベースで更新しました。 –

+0

これでデータベースを更新する方法を見つけることができません。 –

答えて

0

数日間ロジックに苦労した後、ついにそれを手に入れました。誰かがこのようなことに遭遇した場合、これが答えです。私の場合は、ユーザーが自分の画像を変更したときに現在のユーザーのすべての投稿を更新することです(私の投稿では画像のすべてのパスが異なるように非正規化が使用されます)。ポストをループし、現在のユーザーのpostsIDをUserIDに一致するものを見つけて配列に配置し、現在のユーザーの画像を見つけてその配列を画像のパスで更新します。最後にFirebaseデータベースが更新されます!

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 
     self.pathToPictures.removeAll() 

     if snapshot.value as? [String : AnyObject] != 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)) 

        // Update the Database 

        let postIDCount = pathToPostPicture.postID! 
        let updatedUserData = ["posts/\(postIDCount)/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 - add some data") 
     } 

     self.collectionView?.reloadData() 
    }) 
} 
0

を。あなたのデータベースの非正規化は良い習慣ですが、私はこの場合、すべての投稿に同じダウンロードURLを含めない方がよいと主張します。一握りのポストで違いはありませんが、何千ものユーザーと何十万ものポストがあれば、それはダウンロードされる余分なデータがたくさんあります。その代わりに、キーとしてuidを含む辞書と、値としてimageUrlというプロファイルを持つことができます。あなたは、希望のuidの辞書をチェックすることができ、それが存在しない場合は、そのユーザののデータベースを照会して、それらを辞書に追加します。イメージを表示する必要があるときは、この辞書からURLを取得します。他の人がこれについてより良い提案をするかもしれないので、私は他のアイデアを歓迎します。

プロフィール画像をすべての投稿に保存したい場合は、Cloud Functions for Firebaseを使用することをおすすめします。ユーザのでprofileImageUrlが更新されたときに、他の投稿のこのエントリを更新する機能を作成することができます。現在、Cloud関数は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

:これらのリソースをチェック
+0

あなたの答えに感謝します。しかし、現時点で状況から私を救うものではありません。私は原子の更新をする必要があることを知りました。私は私のものが私のために働くコードの種類で私の質問を更新しました。あなたは見て、その部分の作業コードで初心者を助けることができますか?私はFirebaseがあなたのジャムであることを見てきたので、私はあなたを私より賢明であると指名します。 :) –

関連する問題