Balázs Vincze
Balázs Vincze

Reputation: 3832

Update multiple nodes at once Firebase

I am building a chat app and using the following data structure:

enter image description here

Basically in user_chats I am keeping track of all the conversations a user is in, and what was the last_message in that conversation, so that later I can show this in a table view.

In the messages node I am storing all the messages of a given conversation by auto ID.

Now, when the user sends a message it should appear in the messages node of the given conversation, as well as in the last_message of the conversation for both users.

Before I was using dispatch groups and making individual calls to Firebase but that seemed to be very unreliable and inefficient.

How could I updated all the values at the same time efficiently?

Extra: Is this structure good for a 1-1 chat app?

UPDATE WITH WORKING CODE:

I have managed to update all values using the fan-out method.

Here is my code:

    NSDictionary *lastMessageDict = @{[self chatToUserID:userID] : @{@"last_message" : messageBody}};
    NSDictionary *singleMessageDict = @{@"body" : messageBody, @"time_stamp" : kTimeStamp, @"sender" : uID};
    NSString *autoID = [[self.databaseReference child:[NSString stringWithFormat:@"messages/%@/messages",[self chatToUserID:userID]]] childByAutoId].key;
    NSDictionary *messagesDict = @{[self chatToUserID:userID] : @{@"init" : facebookUserID , @"messages" : @{autoID : singleMessageDict}}};

    //Create fan out object
    NSMutableDictionary *fanOut = [NSMutableDictionary new];
    [fanOut addEntriesFromDictionary:@{[NSString stringWithFormat:@"user_chats/%@",uID] : lastMessageDict}];
    [fanOut addEntriesFromDictionary:@{[NSString stringWithFormat:@"user_chats/%@",userID] : lastMessageDict}];
    [fanOut addEntriesFromDictionary:@{@"messages" : messagesDict}];

    [self.databaseReference updateChildValues:fanOut withCompletionBlock:^(NSError *error,FIRDatabaseReference *reference){
        if(error){
            NSLog(@"Error: %@",error);
        }

        else{
            NSLog(@"updated!");
        }
    }];

Upvotes: 0

Views: 685

Answers (1)

Balázs Vincze
Balázs Vincze

Reputation: 3832

With the help of @Frank van Puffelen, I managed to get this working using the fan-out method. Here is my code:

NSDictionary *lastMessageDict = @{[self chatToUserID:userID] : @{@"last_message" : messageBody}};
NSDictionary *singleMessageDict = @{@"body" : messageBody, @"time_stamp" : kTimeStamp, @"sender" : uID};
NSString *autoID = [[self.databaseReference child:[NSString stringWithFormat:@"messages/%@/messages",[self chatToUserID:userID]]] childByAutoId].key;
NSDictionary *messagesDict = @{[self chatToUserID:userID] : @{@"init" : facebookUserID , @"messages" : @{autoID : singleMessageDict}}};

//Create fan out object
NSMutableDictionary *fanOut = [NSMutableDictionary new];
[fanOut addEntriesFromDictionary:@{[NSString stringWithFormat:@"user_chats/%@",uID] : lastMessageDict}];
[fanOut addEntriesFromDictionary:@{[NSString stringWithFormat:@"user_chats/%@",userID] : lastMessageDict}];
[fanOut addEntriesFromDictionary:@{@"messages" : messagesDict}];

[self.databaseReference updateChildValues:fanOut withCompletionBlock:^(NSError *error,FIRDatabaseReference *reference){
    if(error){
        NSLog(@"Error: %@",error);
    }

    else{
        NSLog(@"updated!");
    }
}];

Upvotes: 1

Related Questions