build method

Initialize an AsyncNotifier.

It is safe to use Ref.watch or Ref.listen inside this method.

If a dependency of this AsyncNotifier (when using Ref.watch) changes, then build will be re-executed. On the other hand, the AsyncNotifier will not be recreated. Its instance will be preserved between executions of build.

If this method throws or returns a future that fails, the error will be caught and an AsyncError will be emitted.

Implementation

@override
FutureOr<UserMessagingRepositoryState> build() async {
  _log = ref.watch(appTalkerProvider);
  _log.logCustom(UserMessagingRepositoryLog('build()'));
  _userMessagingService = ref.watch(UserMessagingService.provider);
  _currentUserId = await ref.watch(
      AuthRepository.provider.selectAsync((data) => data.authUser?.uid));

  ///
  Map<String, FCMToken>? fcmTokens;
  if (_currentUserId is String) {
    try {
      final messagingModel =
          await _userMessagingService.getMessaging(_currentUserId!);
      fcmTokens = messagingModel.fcmTokens;
    } catch (err) {
      _log.logCustom(UserMessagingRepositoryLog(
          'getMessaging', err, StackTrace.current));
    }
  }

  ref.listen(currentFbMessagingTokenProvider, (previous, next) async {
    if (_currentUserId is String && next is String) {
      await updateUserFCMToken(next);
    }
  });

  try {
    final settings = await ref.read(fbMessagingProvider).requestPermission(
        alert: true,
        badge: true,
        provisional: true,
        sound: true,
        announcement: true);

    debugPrint('User granted permission: ${settings.authorizationStatus}');
    const vapidKey = const String.fromEnvironment('VAPID_KEY');
    final currentToken =
        await ref.read(fbMessagingProvider).getToken(vapidKey: vapidKey);

    if (currentToken is String && _currentUserId is String) {
      ref.read(currentFbMessagingTokenProvider.notifier).state = currentToken;
    }

    return UserMessagingRepositoryState(
      attachedFCMTokens: fcmTokens,
      currentToken: currentToken,
      notificationSettings: settings,
    );
  } catch (err) {
    /// This might fail, and we should leave it to the user to fix it.
    debugPrint(err.toString());
    UserMessagingRepositoryState(
      attachedFCMTokens: fcmTokens,
      currentToken: null,
      notificationSettings: null,
    );
  }
  return UserMessagingRepositoryState();
}