swift - 快速更新 firebase 数据库的特定部分

标签 swift uitableview firebase firebase-realtime-database

我很难弄清楚如何通过 swift 更改/更新我的 firebase 数据库的特定部分。为了举例说明我的 firebase 数据库的结构,这里有一张照片: enter image description here

每当有人点击我的 tableViewController 中的赞按钮时,我都会尝试更新 likesForPost +1。重要的部分是每个 likesForPost 不应该是更新,只是按钮所在的那个。我希望你能理解我的处境并能帮助我 :-)

我的结构

struct Sweet {
    let key: String!
    let content: String!
    let addedByUser: String!
    let profilePhoto: String!
    var likesForPost: String!
    let itemRef: FIRDatabaseReference?



    init (content: String, addedByUser: String, profilePhoto: String!, likesForPost: String!, key: String = "") {
        self.key = key
        self.content = content
        self.addedByUser = addedByUser
        self.profilePhoto = profilePhoto
        self.likesForPost = likesForPost
        self.itemRef = nil
    }

    init (snapshot: FIRDataSnapshot) {
        key = snapshot.key
        itemRef = snapshot.ref

        if let theFeedContent = snapshot.value!["content"] as? String {
            content = theFeedContent
        } else {
            content = ""
        }

        if let feedUser = snapshot.value!["addedByUser"] as? String {
            addedByUser = feedUser
        } else {
            addedByUser = ""
        }

        if let feedPhoto = snapshot.value!["profilePhoto"] as? String! {
            profilePhoto = feedPhoto
        } else {
            profilePhoto = ""
        }

        if let feedLikes = snapshot.value!["likesForPost"] as? String! {
            likesForPost = feedLikes
        } else {
            likesForPost = "0"
        }

    }

    func toAnyObject() -> AnyObject {
        return ["content":content, "addedByUser":addedByUser, "profilePhoto":profilePhoto!, "likesForPost":likesForPost]
    }
}

我的 UITableViewController

import UIKit
import FirebaseDatabase
import FirebaseAuth
import FBSDKCoreKit

class feedTableViewController: UITableViewController {



    @IBOutlet weak var loadingSpinner: UIActivityIndicatorView!


    var facebookProfileUrl = ""
    var dbRef: FIRDatabaseReference!
    var updates = [Sweet]()

    override func viewDidLoad() {
        super.viewDidLoad()
        loadingSpinner.startAnimating()

        dbRef = FIRDatabase.database().reference().child("feed-items")
        startObersvingDB()

    }

    func startObersvingDB() {
        dbRef.observeEventType(.Value, withBlock: { (snapshot: FIRDataSnapshot) in
            var newUpdates = [Sweet]()

            for update in snapshot.children {
                let updateObject = Sweet(snapshot: update as! FIRDataSnapshot)
                newUpdates.append(updateObject)

            }

            self.updates = newUpdates
            self.tableView.reloadData()


        }) { (error: NSError) in
            print(error.description)
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()

    }




    @IBAction func addToFeed(sender: AnyObject) {
        let feedAlert = UIAlertController(title: "New update", message: "Enter your update", preferredStyle: .Alert)
        feedAlert.addTextFieldWithConfigurationHandler { (textField:UITextField) in
            textField.placeholder = "Your update"
        }
        feedAlert.addAction(UIAlertAction(title: "Send", style: .Default, handler: { (action:UIAlertAction) in
            if let feedContent = feedAlert.textFields?.first?.text {


                if let user = FIRAuth.auth()?.currentUser {
                    let name = user.displayName
                    //let photoUrl = user.photoURL




                    let accessToken = FBSDKAccessToken.currentAccessToken()
                    if(accessToken != nil) //should be != nil
                    {

                        let req = FBSDKGraphRequest(graphPath: "me", parameters: ["fields":"id"], tokenString: accessToken.tokenString, version: nil, HTTPMethod: "GET")
                        req.startWithCompletionHandler({ (connection, result, error : NSError!) -> Void in
                            if(error == nil)
                            {
                                let userId: String! = result.valueForKey("id") as? String!
                                let userID = userId
                                self.facebookProfileUrl = "http://graph.facebook.com/\(userID)/picture?type=large"

                                let likes = "0"

                                let feed = Sweet(content: feedContent, addedByUser: name!, profilePhoto: self.facebookProfileUrl, likesForPost: likes)
                                let feedRef = self.dbRef.child(feedContent.lowercaseString)

                                feedRef.setValue(feed.toAnyObject())




                            }
                            else
                            {
                                print("error \(error)")
                            }
                        })
                    }



                    // LAV FEEDCONTENT OM TIL OGSÅ AT MODTAGE PROFIL BILLEDE URL I STRING OG GIV SÅ facebookProfileUrl STRING LIGE HERUNDER I feed







                } else {
                    // No user is signed in.
                }
            }
        }))

        self.presentViewController(feedAlert, animated: true, completion: nil)


    }





    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return updates.count
    }


    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell:updateTableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! updateTableViewCell


        let update = updates[indexPath.row]

        //cell.textLabel?.text = update.content
        //cell.detailTextLabel?.text = update.addedByUser
        cell.nameLabel.text = update.addedByUser
        cell.updateLabel.text = update.content
        cell.likesLabel.text = "\(update.likesForPost) hi-fives"


        if update.profilePhoto! != "" {
        if let url = NSURL(string: update.profilePhoto!) {
            if let data = NSData(contentsOfURL: url) {
                cell.picView.image = UIImage(data: data)
                cell.picView.layer.cornerRadius = cell.picView.frame.size.width/2
                cell.picView.clipsToBounds = true

            }        
        }
        } else {
            print("Empty facebookProfileUrl")
        }





        loadingSpinner.stopAnimating()

        return cell
    }


}

最佳答案

修改您的结构以包含更多变量(比方说 let path : String!),它将包含从您的数据库(megaTest 或测试)中检索到的节点键的值。

你的结构

   struct Sweet {
let key: String!
let content: String!
let addedByUser: String!
let profilePhoto: String!
var likesForPost: String!
let itemRef: FIRDatabaseReference?
let path : String! 


init (content: String, addedByUser: String, profilePhoto: String!, likesForPost: String!, key: String = "",dataPath : String!) {
    self.key = key
    self.content = content
    self.addedByUser = addedByUser
    self.profilePhoto = profilePhoto
    self.likesForPost = likesForPost
    self.itemRef = nil
    self.path = dataPath
}

init (snapshot: FIRDataSnapshot) {
    key = snapshot.key
    itemRef = snapshot.ref
    path  = key 
    if let theFeedContent = snapshot.value!["content"] as? String {
        content = theFeedContent
    } else {
        content = ""
    }

    if let feedUser = snapshot.value!["addedByUser"] as? String {
        addedByUser = feedUser
    } else {
        addedByUser = ""
    }

    if let feedPhoto = snapshot.value!["profilePhoto"] as? String! {
        profilePhoto = feedPhoto
    } else {
        profilePhoto = ""
    }

    if let feedLikes = snapshot.value!["likesForPost"] as? String! {
        likesForPost = feedLikes
    } else {
        likesForPost = "0"
    }

}

func toAnyObject() -> AnyObject {
    return ["content":content, "addedByUser":addedByUser, "profilePhoto":profilePhoto!, "likesForPost":likesForPost,"pathInTheDB" : path]
    }
}

cellForIndexPath 中添加这个

  cell. pathDB = self.structArray![indexPath.row].path

像这样修改您的 customCell 类

class customTableViewCell : UITableViewCell{

    var pathDB : String! //megaTest or test

     @IBAction func likeBtn(sender : UIButton!){

             //Update like's
         }
      }

要更新值,您可以使用 runTransactionBlock:-

 FIRDatabase.database().reference().child(pathDB).child("likesForPost").runTransactionBlock({ (likes: FIRMutableData) -> FIRTransactionResult in
      // Set value and report transaction success
        likes.value = likes.value as! Int + 1
        return FIRTransactionResult.successWithValue(likes)
      }) { (err, bl, snap) in
        if let error = error {
          print(error.localizedDescription)
        }
      }

或者使用.observeSingleEventOfType观察那个节点,检索快照然后更新

let parentRef = FIRDatabase.database().reference().child(pathDB).child("likesForPost")   
parentRef.observeSingleEventOfType(.Value,withBlock : {(snap) in

 if let nOfLikes = snap.value as? Int{

          parentRef.setValue(nOfLikes+1)

    }

})

关于swift - 快速更新 firebase 数据库的特定部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39452243/

相关文章:

ios - 在 iOS AVPlayer 中,addPeriodicTimeObserverForInterval 似乎丢失了

ios - 多个列,例如使用 UICollectionView Swift 的电子表格表

ios - 通过在本地更新数组模型来重新加载特定的表格 View 单元

firebase - Flutter Streambuilder 不断重建

firebase - 如何使用 Firebase 云消息发送设备到设备消息?

iOS:如何在不使用第三方库或 pod 的情况下在 Swift 中创建可扩展的 TableView

ios - Swift encodeObjectForKey - 用 nil 更新值

ios - fatal error : Dictionary<String, Any> 不符合 Decodable 因为 Any 不符合 Decodable

ios - 带搜索的导航侧边栏

javascript - 使用云功能的推送通知无法运行