我的朋友和我正在开发一个关于swift的IOS项目与新的Firebase集成。我们能够写入Firebase数据库,但是我们在检索数据时遇到了问题。
我们有一个tableView控制器,我们希望从Firebase数据库填充该表。我们的数据库组织如下:
<div class="container-fluid">
<div class="row">
<div class="col-md-2">
<!--Sidebar content-->
<p>
Cauta:
<input ng-model="$ctrl.query" />
</p>
<p>
Sorteaza:
<select ng-model="$ctrl.orderProp">
<option value="name">Alfabetic</option>
</select>
</p>
</div>
<div class="col-md-10">
<!--Body content-->
<ul class="houses">
<li ng-repeat="house in $ctrl.houses |
filter:$ctrl.query |
orderBy:$ctrl.orderProp" class="thumbnail house-list-item">
<a href="#!/houses/{{house.id}}" class="thumb">
<img ng-src="{{house.imageUrl}}" alt="{{house.name}}" />
</a>
<a href="#!/houses/{{house.id}}">{{house.name}}</a>
<p>{{house.price}}</p>
</li>
</ul>
</div>
</div>
</div>
在项目中,我们创建了一个文件/类,它具有写入和从firebase检索的方法。如果我们想要从Firebase检索特定视图控制器的信息,我们只需从该类调用特定方法。
例如,这是该类中的一种方法:
root
|
- Movies
|__ -Wjdkfdmlksdf (unique ID made by Firebase)
|
|_Actors
|_A1 = ajkdfnadfdf
|_A2 = podifpadsfipasdip
|_Title = "Mission Impossible"
|_DirectedBy = "Christopher McQuarrie"
-Actors
|_ -ajkdfnadfdf (unique ID made by Firebase)
|_name : "Tom Cruise"
|_Birthday: xx/yy/zz
我们在func getListOfAllMovieIDs() -> [String] {
let ref = FIRDatabase.database().reference();
var ListOfMovieIDS = [String]();
ref.child("Movies").observeSingleEventOfType(.Value, withBlock: { (snapshot) in
let postDict = snapshot.value as! [String : AnyObject]
for (MID, _) in postDict {
ListOfMovieIDS.append(MID);
}
}) { (error) in
print(error.localizedDescription)
}
return listOfMoviesIDS
}
的{{1}}中称之为上述方法。但是,该方法什么都不返回。我们还调用了另一种方法,比如获取actor的唯一IDS列表,也不返回任何内容。有什么建议吗?
答案 0 :(得分:4)
Firebase异步加载数据。因此,您不会触发请求并等待以获取响应,而是发送请求,然后在某些时候会通知响应。
如果在代码中放置了一些位置很好的日志语句,就可以很容易地看到这一点:
func getListOfAllMovieIDs() {
let ref = FIRDatabase.database().reference();
print("Before listener");
ref.child("Movies").observeSingleEventOfType(.Value, withBlock: { (snapshot) in
print("Inside block");
})
print("After listener");
}
打印报表的顺序为:
听众之前
听众之后
内部块
因此,当您的功能退出时,数据尚未可用。这不是一个错误,而是一个非常有意的选择。通过允许代码继续,应用程序将保持对您的用户的响应。大多数现代互联网都使用这种模式,因此通常最好接受它(尽管最初的问题很棘手)。
解决方案通常是重新编写代码。我们不是说'#34;首先我们加载数据,然后我们做xyz&#34;,说它是&#34;我们开始加载数据,一旦我们得到它,我们做xyz&#34;。这就是Firebase数据加载方法占用块的原因:它包含&#34; xyz&#34;一旦数据可用就应该发生。
这样做的一个很好的副作用是,这个逻辑对于最初加载后可能更新的数据也很有用。当您使用objectEventOfType()
时,您可以轻松处理情况,并且只要我们获取数据,就可以开始同步数据xyz&#34;并有一个处理实时更新的应用程序。
答案 1 :(得分:0)
尝试使用以下方法,因为当您使用observeSingleEventOfType
方法时;返回初始数据后立即取消该块。这可能是您无法在回调块中看到结果的原因。
ref.observeEventType(.Value, withBlock: { snapshot in
println(snapshot.value)
}, withCancelBlock: { error in
println(error.description)
})
答案 2 :(得分:0)
您只需更新以下功能,即可从数据库中获取所有电影ID:
func getListOfAllMovieIDs() -> [String] {
let ref = FIRDatabase.database().reference();
var ListOfMovieIDS = [String]();
ref.child("Movies").observeSingleEventOfType(.Value, withBlock: { (snapshot) in
let postDict = snapshot.children.allObjects as? [DataSnapshot] {
for (index ,movieDict) in postDict.enumerated() {
let movieID = movieDict.key
ListOfMovieIDS.append(movieID);
}
}) { (error) in
print(error.localizedDescription)
}
return ListOfMovieIDS
}