【问题标题】:Firebase on ios is slow in retrieving dataios 上的 Firebase 检索数据很慢
【发布时间】:2016-03-16 16:08:42
【问题描述】:

我了解到,为 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。

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

【问题讨论】:

  • 请编辑您的问题以将 JSON 作为文本包含在内,而不是链接到您的数据结构的图像。链接腐烂。文本图像是 Twitter 的东西,而不是 StackOverflow。
  • 循环体有什么作用?可以出示一下代码吗?
  • 我做了你问的关于@FrankvanPuffelen的编辑
  • 我添加了循环代码@DavidEast
  • 最终目标是什么?您是否尝试填充UITableView?您的设计与异步数据流不匹配。如果您提示我您正在尝试做什么,我可以帮助您制定解决方案以更好地解决您的用例。

标签: ios objective-c firebase data-retrieval


【解决方案1】:

这里的问题是 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 中的存储方式,以便您可以一起检索数据,这样您就不必进行多次观察调用。

【讨论】:

  • 这是有道理的!我试试看!
  • 请查看更新后的答案,因为我写的初始代码不正确。
  • 太棒了!感谢那!这肯定要快很多!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-09
  • 2017-05-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多