每次将 child 添加到 firebase 数据库时都会调用 viewDidLoad
viewDidLoad getting called every time a child is added to firebase database
我正在创建一个聊天视图,下面是我从数据库获取消息的代码,
- (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]}];
}
下面是我的表格视图代码,
- (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 时都会调用它。
我认为你必须检查这一行或者请分享它。
FIRDatabaseReference *id = [firebaseMessagesRef childByAutoId];
这里 class 中发生了什么,在 childByAutoId 中,您的 class(parent/super class) 可能正在再次加载。之间你可以查看这个以供参考。
viewDidLoad is called twice
不是你的 viewDidLoad
被多次调用,而是观察块(它充当一个单独的函数)。
[.. observeEventType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot * _Nonnull snapshot){
根据 documentation、FIRDataEventTypeValue
- "Read and listen for changes to the entire contents of a path.",因此只要您的 firebase 节点发生更改,就会调用您的块。
顺便说一下,如果您希望块只被调用一次,有一个示例 here - 您需要使用方法 observeSingleEventOfType:withBlock:withCancelBlock:
(或 observeSingleEventOfType:withBlock:
)而不是 observeEventType:withBlock:
我正在创建一个聊天视图,下面是我从数据库获取消息的代码,
- (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]}];
}
下面是我的表格视图代码,
- (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 时都会调用它。
我认为你必须检查这一行或者请分享它。
FIRDatabaseReference *id = [firebaseMessagesRef childByAutoId];
这里 class 中发生了什么,在 childByAutoId 中,您的 class(parent/super class) 可能正在再次加载。之间你可以查看这个以供参考。
viewDidLoad is called twice
不是你的 viewDidLoad
被多次调用,而是观察块(它充当一个单独的函数)。
[.. observeEventType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot * _Nonnull snapshot){
根据 documentation、FIRDataEventTypeValue
- "Read and listen for changes to the entire contents of a path.",因此只要您的 firebase 节点发生更改,就会调用您的块。
顺便说一下,如果您希望块只被调用一次,有一个示例 here - 您需要使用方法 observeSingleEventOfType:withBlock:withCancelBlock:
(或 observeSingleEventOfType:withBlock:
)而不是 observeEventType:withBlock: