updateProfilePicture method

Future<void> updateProfilePicture(
  1. BuildContext context,
  2. WidgetRef ref,
  3. String id,
  4. String? photoURL
)

Implementation

Future<void> updateProfilePicture(
  BuildContext context,
  WidgetRef ref,
  String id,
  String? photoURL,
) async {
  ref.read(isInAsyncProvider.notifier).setTrue();

  // Pick an image from the gallery
  final newImage = await imagePickAndCrop(context, 1);
  // If the user cancels the image picker, return
  if (newImage == null) {
    ref.read(isInAsyncProvider.notifier).setFalse();
    return;
  }

  // Upload the image to Firebase Storage
  final fileExtension = await ref
      .read(remoteConfigServiceProvider)
      .getString('image_extension');
  final filePath =
      'avatars/${ref.read(currentUserProvider)!.uid}.$fileExtension';
  final originalStorageUrl = await ref
      .read(storageServiceProvider)
      .uploadFile(newImage, filePath, ImageType.profileOriginal);
  final thumbnailStorageUrl = getThumbnailURL(originalStorageUrl);

  Future.wait([
    if (photoURL == null || photoURL != originalStorageUrl)
      // If the user didn't have a profile picture, set the profile picture
      // url in the user's data. If the user already had a profile picture,
      // update the photo url in the user's data if the new url is different.
      ref.read(authServiceProvider).updatePhotoUrl(originalStorageUrl)
    else ...[
      // If the user already has a profile picture, evict the old image from
      // the cache and reset the url to trigger a reload
      CachedNetworkImage.evictFromCache(originalStorageUrl),
      CachedNetworkImage.evictFromCache(thumbnailStorageUrl),
    ],
  ]).then((_) {
    // Hardcoded delay to ensure everything is in order
    Future.delayed(const Duration(seconds: 2), () {
      ref.read(currentUserProvider.notifier).update(
            (user) => user!.copyWith(
              //https://github.com/Baseflow/flutter_cached_network_image/issues/390#issuecomment-1185059560 ?
              photoURL:
                  '$originalStorageUrl&d=${DateTime.now().millisecondsSinceEpoch}',
            ),
          );
      ref.read(isInAsyncProvider.notifier).setFalse();
    });
  });
}