ios - 每次将 child 添加到 firebase 数据库时都会调用 viewDidLoad

标签 ios objective-c arrays firebase-realtime-database firebaseui

我正在创建一个聊天 View ,下面是我从数据库获取消息的代码,

- (void)viewDidLoad {
FIRDatabaseReference *tenantRef = [[FIRDatabase database] reference];
    [[[[tenantRef child:@"tenantAgreements"] child:userId] child:_propertyId ] observeEventType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot * _Nonnull snapshot){
        //If no previous agreement in teenant agreements for this user or no agreements for this property ID
        if(snapshot.value == [NSNull null]) {
            FIRDatabaseReference *agreementCreateReference = [[[FIRDatabase database] referenceWithPath:@"/agreements/"] childByAutoId];
            agreementId = agreementCreateReference.key;
            NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
            NSString *url = [NSString stringWithFormat:@"https://krib-api-onbit.herokuapp.com/api/agreements?agreementId=%@&listingId=%@",agreementCreateReference.key,_propertyId];
            [request setURL:[NSURL URLWithString:url]];
            [request setHTTPMethod:@"POST"];
            [request setValue:idToken forHTTPHeaderField:@"X-FIREBASE-ID-TOKEN"];
            [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];

            NSURLSession *session = [NSURLSession sharedSession];
            NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                NSString *res = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            }];
            [dataTask resume];
        }
        else{ //If already a agreements for this property for this user exist.
            agreementId = snapshot.value;
            FIRDatabaseReference *getMessagesRef = [[FIRDatabase database] referenceWithPath:[NSString stringWithFormat:@"/messages/%@",snapshot.value]];
            [getMessagesRef observeEventType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot * snapshot) {
                NSLog(@"snapshotssnapshots %@",snapshot);
                if(snapshot != NULL){
                    for(snapshot in snapshot.children){
                        [self.arr_text addObject:snapshot];
                    }
                    [self.tableView reloadData];
                }
            }];
        }
    }];
}

每当我在输入内容后单击文本字段中的发送按钮时,viewDidLoad 就会再次被调用,并且它会再次向 self.arr_text 添加数据。下面是我点击发送按钮的代码,

- (IBAction)getMessage:(id)sender {
    FIRDatabaseReference *firebaseMessagesRef = [[FIRDatabase database] reference];
    FIRDatabaseReference *id = [firebaseMessagesRef childByAutoId];
    [[[[firebaseMessagesRef child:@"messages"] child:agreementId] child:id.key] setValue:@{@"senderId":userId,@"text":_textField.text,@"timestamp":[FIRServerValue timestamp]}];
}

下面是我的表格 View 代码,

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *cellIdentifier = @"myCell";
    ChatTableViewCell *cell =[tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    FIRDataSnapshot *snaps = [self.arr_text objectAtIndex:indexPath.row];
    cell.mylabel.text = snaps.value[@"text"];
    cell.mylabel.backgroundColor = [UIColor grayColor];
    cell.mylabel.layer.masksToBounds = YES;
    cell.mylabel.layer.cornerRadius = 8.0;

    cell.myImg.layer.cornerRadius = cell.myImg.frame.size.width/2;;
    cell.myImg.clipsToBounds = YES;
    [cell.myImg setImage:[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[profile valueForKey:@"photoUrl"]]]]];
    return cell;
}

我找不到为什么每当我向数据库添加新 child 时都会调用它。

最佳答案

被多次调用的不是您的 viewDidLoad,而是观察 block (作为一个单独的函数)。

[.. observeEventType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot * _Nonnull snapshot){

根据documentation , FIRDataEventTypeValue - “读取并监听路径的全部内容的变化。”,所以只要你的 firebase 节点发生变化,你的 block 就会被调用。

顺便说一句,如果你想让这个 block 只被调用一次,有一个例子here - 您需要使用方法 observeSingleEventOfType:withBlock:withCancelBlock:(或 observeSingleEventOfType:withBlock:)而不是 observeEventType:withBlock:

关于ios - 每次将 child 添加到 firebase 数据库时都会调用 viewDidLoad,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42414944/

相关文章:

objective-c - Swift 模块不使用 L10N 中的本地化内容

c# - Xamarin:如何使用 YES 实现 NSDictionary

arrays - 在有序数组中快速查找元素

iPhone - 以编程方式更改应用程序设置

ios - 如何检测页面 View Controller 上的滑动?

ios - Objective C 中的位掩码

ios - 如何在 Store Kit 应用内购买中测试取消订阅?

ios - Interface Builder 生成非 ARC 代码

javascript - 如何接近和对齐数组中的元素?

python - 基于距离的分类