2017-02-23 66 views
0

Я создаю вид чата и ниже мой код, чтобы получать сообщения из БД,viewDidLoad вызывался каждый ребенок добавляется firbase БД При

- (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]}]; 
} 

Ниже мой TableView код,

- (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; 
} 

Я не могу найти, почему он вызывался всякий раз, когда я добавляю новый ребенок в БД.

ответ

3

Это не ваш viewDidLoad, который вызывается несколько раз, это блок наблюдения, что делает (который действует в качестве отдельной функции).

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

Согласно documentation, FIRDataEventTypeValue - «Читать и слушать изменений всего содержимого пути.», Так что ваш блок будет вызываться всякий раз, когда происходит изменение в вашем firebase узле.

Кстати, если вы хотите, чтобы блок будет называться только один раз, есть пример here - вам нужно использовать метод observeSingleEventOfType:withBlock:withCancelBlock: (или observeSingleEventOfType:withBlock:) вместо observeEventType:withBlock:

1

Я думаю, вы должны проверить эту строку или поделиться ею.

FIRDatabaseReference *id = [firebaseMessagesRef childByAutoId]; 

Вот что происходит в этом классе, в childByAutoId, это может быть возможно, что ваш класс (родитель/супер класс) снова загружается. Между вами вы можете проверить это для справки.

viewDidLoad is called twice

Смежные вопросы