ios 上的 Firebase 检索数据缓慢
Firebase on ios is slow in retrieving data
我了解到,保持 Firebase 的数据扁平化以及仅嵌套您打算调用的数据非常重要。我已经完成了那些事情,但 Firebase 在检索数据方面仍然太慢。这是一个例子:
我的数据是这样的:
--English
----Ari : 4
----Philip : 2
----John : 6
我的代码如下所示:
[super viewDidLoad];
[[DataSource sharedInstance].selectedLanguageMutableArray removeAllObjects];
//Retrieving Data From Firebase
NSString* selectedLanguagePath = [NSString stringWithFormat:@"languages/%@", [DataSource sharedInstance].languageSelected];
Firebase *languagesRef = [[DataSource sharedInstance].ref childByAppendingPath:selectedLanguagePath];
[[languagesRef queryOrderedByValue] observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot *snapshot) {
[self.distanceMutableArray addObject:snapshot.key];
NSLog(@"%@", snapshot.key);
NSLog(@"%@", snapshot.value);
NSLog(@"%@", self.distanceMutableArray);
}];
//Selected Languages Mutable Array
[[DataSource sharedInstance].selectedLanguageMutableArray removeAllObjects];
for (NSInteger i = 0; i < self.distanceMutableArray.count; i++) {
UserCustomizationData *item = [[UserCustomizationData alloc] init];
NSString* selectedUser = self.distanceMutableArray[i];
Firebase* selectedUserRef = [[DataSource sharedInstance].usersRef childByAppendingPath:selectedUser];
if (selectedUser.length > 0) {
Firebase* profilePicRef = [selectedUserRef childByAppendingPath:@"profilePicture"];
[profilePicRef observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot *snapshot) {
NSString* profPicString = snapshot.value;
NSData *dataFromBase64=[NSData base64DataFromString:profPicString];
UIImage *profPicImage = [[UIImage alloc]initWithData:dataFromBase64];
item.profilePicture = profPicImage;
}];
[[DataSource sharedInstance].selectedLanguageMutableArray addObject:item];
}
}
但是,self.distanceMutableArray 之前的 for 循环 运行 可以填充。这会抛出一切,因为 for 循环依赖于 self.distanceMutableArray 被填充。
有没有一种方法可以检索数据,使代码 运行 流畅并按编写的顺序进行?
这里的问题是 Firebase 通过异步调用工作;您的代码将无法始终如一地工作,因为 Firebase 块下方的代码可能会在该块完成之前被调用。
您将需要开始异步编码,并且只有在确定快照数据已填充(在块内)后才对快照数据执行操作
[[languagesRef queryOrderedByValue] observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot *snapshot) {
//at this point, firebase has loaded the snapshot
// so its available to work with
[self.distanceMutableArray addObject:snapshot.key];
for (NSInteger i = 0; i < self.distanceMutableArray.count; i++) {
//do some stuff with the items in snapshot
}
}];
//don't work with anything that was from the snapshot as it may have not been filled yet
然而,由于代码使用的是 childAdded,因此存在一个问题,因此它将遍历 firebase 节点中的每个项目,因此该代码将无法正常工作,因为它无法正确加载数组(是的,我们可以修复通过在每个循环期间填充数组)。
这里的额外挑战是您需要根据第一个快照的结果从 Firebase 检索数据。同样,存在同样的情况;仅在确定数据已被检索后才对该检索到的数据执行操作。
一种解决方案是一次加载整个数据集并对其进行迭代(按值而不是添加)。如果您的数据集较小,则可行。但是,对于大数据集来说可能太多了。
[[languagesRef queryOrderedByValue] observeEventType:FEventTypeValue withBlock:^(FDataSnapshot *snapshot) {
//at this point, firebase has loaded the snapshot
// so its available to work with and loaded with
//everything in the node
for ( FDataSnapshot *child in snapshot.children) {
NSDictionary *dict = child.value;
NSString *uid = child.key;
[self.distanceMutableArray addObject:uid];
}
// now the array is loaded do something with it
}];
另一种选择是更改您的数据在 firebase 中的存储方式,这样您就可以一起检索数据,而不必进行多次观察调用。
我了解到,保持 Firebase 的数据扁平化以及仅嵌套您打算调用的数据非常重要。我已经完成了那些事情,但 Firebase 在检索数据方面仍然太慢。这是一个例子:
我的数据是这样的:
--English
----Ari : 4
----Philip : 2
----John : 6
我的代码如下所示:
[super viewDidLoad];
[[DataSource sharedInstance].selectedLanguageMutableArray removeAllObjects];
//Retrieving Data From Firebase
NSString* selectedLanguagePath = [NSString stringWithFormat:@"languages/%@", [DataSource sharedInstance].languageSelected];
Firebase *languagesRef = [[DataSource sharedInstance].ref childByAppendingPath:selectedLanguagePath];
[[languagesRef queryOrderedByValue] observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot *snapshot) {
[self.distanceMutableArray addObject:snapshot.key];
NSLog(@"%@", snapshot.key);
NSLog(@"%@", snapshot.value);
NSLog(@"%@", self.distanceMutableArray);
}];
//Selected Languages Mutable Array
[[DataSource sharedInstance].selectedLanguageMutableArray removeAllObjects];
for (NSInteger i = 0; i < self.distanceMutableArray.count; i++) {
UserCustomizationData *item = [[UserCustomizationData alloc] init];
NSString* selectedUser = self.distanceMutableArray[i];
Firebase* selectedUserRef = [[DataSource sharedInstance].usersRef childByAppendingPath:selectedUser];
if (selectedUser.length > 0) {
Firebase* profilePicRef = [selectedUserRef childByAppendingPath:@"profilePicture"];
[profilePicRef observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot *snapshot) {
NSString* profPicString = snapshot.value;
NSData *dataFromBase64=[NSData base64DataFromString:profPicString];
UIImage *profPicImage = [[UIImage alloc]initWithData:dataFromBase64];
item.profilePicture = profPicImage;
}];
[[DataSource sharedInstance].selectedLanguageMutableArray addObject:item];
}
}
但是,self.distanceMutableArray 之前的 for 循环 运行 可以填充。这会抛出一切,因为 for 循环依赖于 self.distanceMutableArray 被填充。
有没有一种方法可以检索数据,使代码 运行 流畅并按编写的顺序进行?
这里的问题是 Firebase 通过异步调用工作;您的代码将无法始终如一地工作,因为 Firebase 块下方的代码可能会在该块完成之前被调用。
您将需要开始异步编码,并且只有在确定快照数据已填充(在块内)后才对快照数据执行操作
[[languagesRef queryOrderedByValue] observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot *snapshot) {
//at this point, firebase has loaded the snapshot
// so its available to work with
[self.distanceMutableArray addObject:snapshot.key];
for (NSInteger i = 0; i < self.distanceMutableArray.count; i++) {
//do some stuff with the items in snapshot
}
}];
//don't work with anything that was from the snapshot as it may have not been filled yet
然而,由于代码使用的是 childAdded,因此存在一个问题,因此它将遍历 firebase 节点中的每个项目,因此该代码将无法正常工作,因为它无法正确加载数组(是的,我们可以修复通过在每个循环期间填充数组)。
这里的额外挑战是您需要根据第一个快照的结果从 Firebase 检索数据。同样,存在同样的情况;仅在确定数据已被检索后才对该检索到的数据执行操作。
一种解决方案是一次加载整个数据集并对其进行迭代(按值而不是添加)。如果您的数据集较小,则可行。但是,对于大数据集来说可能太多了。
[[languagesRef queryOrderedByValue] observeEventType:FEventTypeValue withBlock:^(FDataSnapshot *snapshot) {
//at this point, firebase has loaded the snapshot
// so its available to work with and loaded with
//everything in the node
for ( FDataSnapshot *child in snapshot.children) {
NSDictionary *dict = child.value;
NSString *uid = child.key;
[self.distanceMutableArray addObject:uid];
}
// now the array is loaded do something with it
}];
另一种选择是更改您的数据在 firebase 中的存储方式,这样您就可以一起检索数据,而不必进行多次观察调用。