【问题标题】:How can I show data correctly in a UITableViewController with Firebase?如何使用 Firebase 在 UITableViewController 中正确显示数据?
【发布时间】:2017-11-09 18:40:08
【问题描述】:

我正在构建一个类似于“instagram”的应用程序,其中包含带有图片的帖子。我正在使用 Firebase 存储/检索数据。

我的问题出现是因为帖子以随机方式显示。比如cellForRowAtIndexPath,第一个帖子显示在indexPath[0],下一个帖子是[1],但是下一个应该在[2]的帖子显示在[0]。

我将复制粘贴与该问题最相关的代码:

这是我检索分数的课程:

////// Arrays to store the data
nameArray = [[NSMutableArray alloc]init];
scoreArray = [[NSMutableArray alloc]init];
photomealArray = [[NSMutableArray alloc]init];
keysArray = [[NSMutableArray alloc]init]; // Reference to know what post should be scored. 


// Reference to the Database
self.storageRef = [[FIRStorage storage] reference];
FIRDatabaseReference *rootRef= [[FIRDatabase database] referenceFromURL:@"https://XXXXXXX.firebaseio.com/"];


// Query all posts
[[rootRef child:@"Posts"] observeSingleEventOfType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot * _Nonnull snapshot) {

    if(snapshot.exists){

        NSDictionary *dict = snapshot.value;
        for (NSString *key in dict) {

            // Query all users to show the Name of the person who posts
            [[rootRef child:@"Users"] observeEventType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot * _Nonnull Usersnapshot) {

                if(Usersnapshot.exists){
                    NSDictionary *Userdict = Usersnapshot.value;
                    for (NSString *Userkey in Userdict) {


                        NSString *Users_UserID = [Userdict[Userkey] valueForKey:@"UserID"];
                        NSString *UserID = [dict[key] valueForKey:@"UserID"];
                        // If the userID matches with the person who posts, then add it to the array
                        if([Users_UserID isEqualToString:UserID]) [nameArray addObject:[NSString stringWithFormat:@"%@",[Userdict[Userkey] valueForKey:@"Name"]]];

                    }
                }

            }];

            UIImage *mealPhoto = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL   URLWithString:[dict[key] valueForKey:@"PostPhoto"]]]];

            NSString *Score = [dict[key] valueForKey:@"Score"];
            NSString *PostKeys = [dict[key] valueForKey:@"KeyforPost"];
            if([Score isEqual:@"null"]) [scoreArray addObject:@"0"]; else [scoreArray addObject:Score];
            [photomealArray addObject:mealPhoto];
            [keysArray addObject:PostKeys];

        }

    }
} withCancelBlock:^(NSError * _Nonnull error) {
    NSLog(@"%@", error.localizedDescription);
}];

如果我退出并重新启动应用程序,新帖子将存储在从 [0] 开始的任何“空”索引中,这是预期的。

didSelectRowAtIndexPath 是这样的:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath{

FeedTableViewCell *cell =[tableView cellForRowAtIndexPath:indexPath];

if(cell.selectionStyle != UITableViewCellSelectionStyleNone){

    if([score.text intValue] >= -1 && [score.text intValue] <= 1 && ![score.text  isEqual: @""]){

            NSString *keyforcell = [keysArray objectAtIndex:indexPath.row];

            NSLog(@"key a usar :%@", keyforcell);

             ref = [[FIRDatabase database] referenceFromURL:@"https://XXXXX.firebaseio.com"];


            [[[[self.ref child:@"Posts"] child:keyforcell] child:@"Score"] setValue:[NSNumber numberWithInt:[score.text intValue]]];

            [[[[self.ref child:@"Posts"] child:keyforcell] child:@"Rated"] setValue:@"YES"];

            [scoreArray insertObject:[NSNumber numberWithInt:[score.text intValue]] atIndex:indexPath.row];

            cell.selectionStyle = UITableViewCellSelectionStyleNone;
    }

}

我尝试过使用observeSingleEventOfTypeobserveEventType,因为这可能与单个只被调用一次的事实有关。我还认为viewDidLoad() 在选择单元格后被触发,但它不应该。另外,我认为它与 NSMutableArrays 有关,但我不完全确定

谁能帮帮我?

更新:我知道 Firebase 和 NSDictionary 都不会返回/存储排序数据,所以我的猜测是我的问题与排序项目有关。我了解了orderbykeyorderbyvalue,但它们似乎不起作用。

【问题讨论】:

    标签: ios objective-c uitableview firebase firebase-realtime-database


    【解决方案1】:

    不清楚您的问题是什么,但您不应忘记 Firebase 数据库中没有数组。唯一的集合类型是字典,字典没有键顺序。

    您应该考虑对对象使用排序系统,而不是直接将它们添加到数组中。

    【讨论】:

    • 是的,你是对的 :) 但是.....我从来没有说过 Firebase 中有数组。我的意思是我知道返回的查询需要存储在字典中。只是为了澄清,问题是当帖子加载到 viewdidload() (创建后)时,它会显示在随机单元格中。我认为这与 NSMutableArrays 有关,但我不是 100% 确定
    • "它显示在随机单元格中" >> 这听起来就像您依赖字典对象中键的顺序,而字典对象不存在。您使用的是for (NSString *key in dict),它不能保证任何订单。
    • 其实这点很好。由于 NSDictionary 不保证对项目进行排序,因此项目不会总是在 NSMutablearray 中排序(就我而言)。所以我应该做的是以与存储在 Firebase 中相同的方式对 Dict 中的键值进行排序,不是吗?
    • "与它们在 Firebase 中的存储方式相同" >> 它们在 Firebase 中也没有排序,即使它们看起来是这样。仅仅因为它们有012 之类的键,并不意味着它们已排序。我第三次重复 :) “字典无法排序”。首先,您应该了解这个简单的事实,然后您可以决定对您的对象进行排序的方法。您可以在对象中使用键值或任何其他信息。这取决于您的应用逻辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多