createRoom method

Future<Room> createRoom(
  1. User otherUser, {
  2. Map<String, dynamic>? metadata,
})

Creates a direct chat for 2 people. Add metadata for any additional custom data.

Implementation

Future<types.Room> createRoom(
  types.User otherUser, {
  Map<String, dynamic>? metadata,
}) async {
  final fu = firebaseUser;

  if (fu == null) return Future.error('User does not exist');

  // Sort two user ids array to always have the same array for both users,
  // this will make it easy to find the room if exist and make one read only.
  final userIds = [fu.uid, otherUser.id]..sort();

  final roomQuery = await getFirebaseFirestore()
      .collection(config.roomsCollectionName)
      .where('type', isEqualTo: types.RoomType.direct.toShortString())
      .where('userIds', isEqualTo: userIds)
      .limit(1)
      .get();

  // Check if room already exist.
  if (roomQuery.docs.isNotEmpty) {
    final room = (await processRoomsQuery(
      fu,
      getFirebaseFirestore(),
      roomQuery,
      config.usersCollectionName,
    ))
        .first;

    return room;
  }

  // To support old chats created without sorted array,
  // try to check the room by reversing user ids array.
  final oldRoomQuery = await getFirebaseFirestore()
      .collection(config.roomsCollectionName)
      .where('type', isEqualTo: types.RoomType.direct.toShortString())
      .where('userIds', isEqualTo: userIds.reversed.toList())
      .limit(1)
      .get();

  // Check if room already exist.
  if (oldRoomQuery.docs.isNotEmpty) {
    final room = (await processRoomsQuery(
      fu,
      getFirebaseFirestore(),
      oldRoomQuery,
      config.usersCollectionName,
    ))
        .first;

    return room;
  }

  final currentUser = await fetchUser(
    getFirebaseFirestore(),
    fu.uid,
    config.usersCollectionName,
  );

  final users = [types.User.fromJson(currentUser), otherUser];

  // Create new room with sorted user ids array.
  final room = await getFirebaseFirestore()
      .collection(config.roomsCollectionName)
      .add({
    'createdAt': FieldValue.serverTimestamp(),
    'imageUrl': null,
    'metadata': metadata,
    'name': null,
    'type': types.RoomType.direct.toShortString(),
    'updatedAt': FieldValue.serverTimestamp(),
    'userIds': userIds,
    'userRoles': null,
  });

  return types.Room(
    id: room.id,
    metadata: metadata,
    type: types.RoomType.direct,
    users: users,
  );
}