arvidurs
arvidurs

Reputation: 3033

Firebase ObserveEvent childAdded wait until done

I am using the new firebase api to observe a child path in the realtime database called "posts"

Here is one JSON Entry:

"posts" : {

"-KLT6oYF-F_5sf-dC_2R" : {
  "items" : {
    "item1" : {
      "location" : "Post Street Mall",
      "name" : "Glasses",
      "price" : "199",
      "vendor" : "Clicks"
    }},      
  "tags" : "summer, casual, urban ",
  "title" : "Casual Summer "
}

The problem is whenever I add something to "posts" the childAdded event is fired and my app database updates. Unfortunately not all the data has been added yet using setValue().

Is there a way to only write to the database when all the items and has been added? And then when all the data for one post has been added, send the childAdded signal to the app?

Any help is much appreciated.

Basic sample code follows:

    // CREATING DATABASE OBSERVER TO SCAN POSTS

    let postRef = database.child("posts")
    // CONNECTING OBSERVER AND CHECKING FOR NEW ITEMS
    postRef.observeEventType(.ChildAdded, withBlock: { (snapshot) -> Void in

     // This is in a different class
     postDBRef.child("title").setValue(self.mainImageTxt?.text) // I think this triggers the child added already?                postDBRef.child("tags").setValue(self.tagsTxt?.text?.lowercaseString)                
     // getting cell data
     for rowIndex in 0..<self.stepperValue {
         let cell = self.tableView.cellForRowAtIndexPath(NSIndexPath(forRow: rowIndex, inSection: 0)) as! AddPostTableViewCell
         let itemName = cell.itemNameTxt.text!
         postDBRef.child("items/item\(rowIndex + 1)/name").setValue(itemName)
          }

Upvotes: 0

Views: 786

Answers (2)

Jay
Jay

Reputation: 35657

Build an object in code, say a dictionary and write it out at one time! That will eliminate having to do that iteration. You can then do setValue(myObject) and the problem goes away.

I whipped up some quick code to produce the data structure similar to what you're using. This will build the structure in code and then write it out with one setValue.

Assume you want the following data structure

items
  item4
    name: some item 3
  item8
    name: some item 7

Here's how to do get that in code

    let stepperValue = 10
    var myDict = [String:  [String: String] ]()

    for rowIndex in 0..<stepperValue {
        let itemName = "some item \(rowIndex)"
        let childDict = ["name": itemName]
        let parentKey = "item\(rowIndex + 1)"
        myDict[parentKey] = childDict
    }

    let ref = myRootRef.childByAppendingPath("items")
    ref.setValue(myDict)

Upvotes: 1

adolfosrs
adolfosrs

Reputation: 9389

You could simply go with updateChildValues, keeping the changes you want to write in an array

 let childUpdates = ["/posts/\(postKey)": postData,
                    "/posts/\(anotherPostId)": anotherPostData]

And when you have all the posts you want to update you just call

ref.updateChildValues(childUpdates)

This will write the data once and it will call one ChildAdded event for each child you have added.

Documentation here.

Upvotes: 1

Related Questions