ios上的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]; } } 

但是,for循环在self.distanceMutableArray可以填充之前运行。 这会抛出所有的东西,因为for循环依赖于被填充的self.distanceMutableArray。

有没有一种方法来检索数据,以使代码能够stream畅地运行并按照它的编写顺序运行?

这里的问题是,Firebase通过asynchronous调用进行工作。 您的代码将无法保持一致,因为可能会在块完成之前调用Firebase块下面的代码。

您将需要asynchronous开始编码,并且只有在确定已填充(在块内)之后才对快照数据执行操作,

  [[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中检索数据。 同样的情况也存在; 只有在确定检索到数据后,才会对检索到的数据执行操作。

一个解决scheme是一次加载整个数据集,然后迭代(通过值而不是添加)。 如果你的数据集较小,那么工作。 但是,大数据集可能太多了。

 [[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中的存储方式,以便您可以一起检索数据,因此不必进行多次观察调用。