This works, like you've shown, because of pointers to this data structures. If we will go 'under the hood' of the language (not only Dart, it could be Java also).
In your example you assign to 'data' variable a pointer to 'dataUser', not a new instance or copy of this data.
What is pointer? With pointer you show compiler the address of the memory, where data is stored, and give a way of modifying them.
So, let's return to your example:
Map<String, dynamic> dataUser = {
'name': group.name,
'simplify_group_debts': group.simplifyGroupDebts,
'admin_user': group.adminUser,
'timestamp': ServerValue.timestamp,
};
Map<String, dynamic> data = dataUser;
data.putIfAbsent('members', () => {user.uid: true});
In line 2 you assign to 'data' variable the pointer to 'dataUser', so in 'data' we have exactly the same data address, as 'dataUser' has.
Map<String, dynamic> data = dataUser;
Instead, to avoid such behavior, you need to create new instance (give it own memory address/room to store data) of 'dataUser's Map, using .from method:
var data = Map.from(dataUser);
Which will create you new, independent instance from 'dataUser' map, with its unique memory address pointer. So, when you will mutate 'dataUser' or 'data' map, they will not mutate each other, each map will change only itself.