I would like to make a chat using Firebase. I need to display for each users the list of group they belong to and also for each group all the members.
Because of how Firebase is designed, and in order to have acceptable performance, I am think making a list of all the groups containing the list of members, and for each users, an entry with all the group they belong too.
My first question is, is it the right approach?
If so, my second question is how can I atomically add (or removed) a user, i.e. making sure both the user is added in the group and the group added into the user or not added at all (i.e. never stored at 1 location only and make the DB inconsistent) ?
The data model you have proposed is consistent with recommendations for firebase. A more detailed explanation is outlined in best way to structure data in firebase
users/userid/groups
groups/groupid/users
Firebase provides .transaction for atomic operations. You may chain multiple transactions to ensure data consistency. You may also use onComplete callback function. For detailed explanation refer to firebase transaction. I am using this same approach to keep multiple message counts up to date for a dashboard display.
Sample code for nested transaction:
ref.child('users').child(userid).child(groupid).transaction(function (currentData) {
if (currentData === null) {
return groupid;
} else {
console.log('groupid already exists.');
return; // Abort the transaction.
}
}, function (error, committed, snapshot) {
if (committed) {
console.log('start a new transaction');
ref.child('groups').child(groupid).child(userid).tranaction(function (currentData) {
if (currentData === null) {
return userid;
} else {
console.log('Userid already exists.');
//add code here to roll back the groupid added to users
return; // Abort the transaction.
}
}, function (error, committed, snapshot) {
if (error) {
//rollback the groupid that was added to users in previous transaction
}
})
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With