updateUserFCMToken method

Future<UserMessagingModel> updateUserFCMToken(
  1. String userId,
  2. FCMToken token
)

Implementation

Future<UserMessagingModel> updateUserFCMToken(
    String userId, FCMToken token) async {
  final usersRef = _db.collection('Users');

  final userRef = usersRef.doc(userId);
  final userTokensRef = userRef.collection('Tokens');
  try {
    await _db.runTransaction((tx) async {
      final userSnapshot = await tx.get(userRef);

      if (userSnapshot.exists) {
        var model =
            await UserMessagingModel.fromDocumentSnapshot(userSnapshot);
        if (token.id == null) {
          token = token.copyWith(id: userTokensRef.doc().id); // Virtual ID
        }
        final fcmTokens = model.fcmTokens ?? <String, FCMToken>{};

        /// Check if token already exists in fcmTokens.token
        final sameToken =
            fcmTokens.values.where((element) => element.token == token.token);
        if (sameToken.length > 0) {
          return model;
        }

        fcmTokens[token.id!] = token;
        model = model.copyWith(
          fcmTokens: fcmTokens,
          updatedAt: DateTime.now().millisecondsSinceEpoch.toDouble(),
        );
        tx.set(userRef, model.toJson());
      } else {
        throw UserMessagingDataServiceException(
            code: RdevCode.NotFound,
            message: 'User with id:${userId} was not found');
      }
    });

    final snapshot = await userRef.get();
    final updatedModel =
        await UserMessagingModel.fromDocumentSnapshot(snapshot);
    return updatedModel;
  } catch (err) {
    if (err is UserMessagingDataServiceException) {
      rethrow;
    }
    throw UserMessagingDataServiceException(message: err.toString());
  }
}