【问题标题】:how to retrieve firebase database values to calculate average如何检索firebase数据库值以计算平均值
【发布时间】:2019-02-25 09:15:16
【问题描述】:

我一直在尝试创建一个社交应用,让人们可以对他人进行评分。我已经能够检索和显示每条评论的评分,但是我很难获得所有评分来计算平均值。

这是我的代码:

 func observeStars() {

    guard let toId = users?.id else {
        return }
    let placesRef = Database.database().reference().child("Review")

    placesRef.observeSingleEvent(of: .value, with: { snapshot in

        for child in snapshot.children {

            let placeSnap = child as! DataSnapshot
            let ratingsSnap = placeSnap.childSnapshot(forPath: "STAR")
            print(ratingsSnap)
            let count = ratingsSnap.childrenCount
            var total: Double = 0.0
            for child in ratingsSnap.children {
                print(child)
                let snap = child as! DataSnapshot
                let val = snap.value as! Double
                total += val
            }
            let average = total/Double(count)
            print(average)

        }
    })
}

我的 firebase 数据库结构如下所示:

{  
"Review" : {  

"75YFHCGX8WQyP3qlyvQKNohgCvQ2" : {  
  "-LM9OW1eLcS9yr3JZxP5" : {  
    "FROM" : "AV4RFwIlSNdnryfPPCl6SfLOzBZ2",  
    "STAR" : 3,  

    "TIMESTAMP" : 1.5366990112576609E9,  
    "TO" : "75YFHCGX8WQyP3qlyvQKNohgCvQ2"  
  },  

  "-LM9OoyD8A8HWZ387Ln9" : {  
    "FROM" : "MAc9ouJnAacHddqDMRet3K9SkZq1",  
    "STAR" : 2,  

    "TIMESTAMP" : 1.5366990928939629E9,  
    "TO" : "75YFHCGX8WQyP3qlyvQKNohgCvQ2"  
  }  
},  

"MAc9ouJnAacHddqDMRet3K9SkZq1" : {  
  "-LM9Oa1zGbRjdCERwoDX" : {  
    "FROM" : "AV4RFwIlSNdnryfPPCl6SfLOzBZ2",  
    "STAR" : 4,  

    "TIMESTAMP" : 1.536699031758939E9,  
    "TO" : "MAc9ouJnAacHddqDMRet3K9SkZq1"  
  }  
}  

我想使用子节点“STAR”进行计算

请,任何帮助将不胜感激!

【问题讨论】:

  • 请不要在问题中包含图片和链接。包括代码和结构作为文本。要获取您的 Firebase 结构,请使用 Firebase 控制台->导出 JSON 并复制粘贴您的结构的 sn-p。见images and links are evil

标签: swift firebase dictionary firebase-realtime-database


【解决方案1】:

这就是问题所在;结构可能太深,您的代码与结构不匹配。

您正在观察有两个子节点的 Review 节点

Review
   -75YFH...
   -MAc9ou...

请记住,那些子节点也有子节点。

-7590W...
   -LM90W...
   -LM90o...
-MAc9ou...
   -LM90a

for 循环在 -75YFH 和 -MAc9ou 的顶级子节点上循环所以这段代码

let placeSnap = child as! DataSnapshot
let ratingsSnap = placeSnap.childSnapshot(forPath: "STAR")

真的

let ratingsSnap = -75YFH.childSnapshot(forPath: "STAR")

let ratingsSnap = -MAc9ou.childSnapshot(forPath: "STAR")

如您所见,STAR 不是这些节点的子节点。

根据您的结构,-75YFH 和 -MAc9ou 的两个顶部节点中的每一个都需要另一个循环来迭代它们的子节点并检索 STAR 节点

   var counter = 0      
   placesRef.observeSingleEvent(of: .value, with: { snapshot in
        for child in snapshot.children { //this is -75YFH and -MAc9ou
            let placeSnap = child as! DataSnapshot 
            for childOfPlace in placeSnap.children { //this is -LM90W and -LM90o
                 let childOfPlaceSnap = childOfPlace as! DataSnapshot                     
                 //let ratingsSnap = childOfPlaceSnap.childSnapshot(forPath: "STAR")
                 //I prefer the following...
                 let dict = childOfPlaceSnap.value as! [String: Any]
                 let val = dict["STAR"] as! Int
                 counter += val
            }
        }
        print("total stars: \(counter)") //or tableView.reloadData()
    })

注意:该代码是在我的 iPad 上键入的,因此未经测试,因此请勿复制粘贴。这个概念是合理的。

【讨论】:

  • 感谢杰伊的回复。我可以使用您建议的代码获得不同的 STAR 值。但是当我尝试在每个子节点下添加值时,它只显示单个值而不是值的总和。我使用了以下代码: let dict = childOfPlaceSnap.value as! [String: Any] 让 val = dict["STAR"] as! Int var total: Int = 0 total += val let average = total/Int(count)
  • @estelyk 我把总和留给你了。但我已经用一个简单的计数器将它添加到计数中。
  • 所以,我再次尝试了该代码,但是当我在控制台中加载数据时,我注意到它从上到下从 -7590W... 和 -MAc9ou... 节点运行了 3 次。另一个问题是,当我尝试获得 STARS 的总数时,控制台显示的是 3、5、9,而不是从 -7590W 获得“5”,而从 -MAC9 获得“4”。这些值再次重复 3 次。平均值最终为“1.5”、“2.5”、“9”,而不仅仅是 2.5 和 4。再次感谢您的建议!
  • 没关系,我想我想通了。我忘了我正在使用 tableViewCell 中的函数。也许这就是为什么要多次读取数据的原因?
  • @estelyk 使用 .observeSingleEvent 时,数据将不会被多次读取。整个节点将被读取一次,不会留下任何观察者,因此不会产生其他事件。问题是,如果将函数放在 tableView 单元格中,则每次创建/更新单元格时,都会调用该函数。那是错误的设计模式;应该在 viewDidLoad 中调用它来填充您的数据源,然后调用 tableView.reloadData() 以在 tableView 中显示加载的数据。 tableView.reloadData() 就在 print 语句所在的位置。
猜你喜欢
  • 1970-01-01
  • 2010-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-07
相关资源
最近更新 更多