MediaLibrary Album asset array is not up to date immediately after new photo was added

#1

After taking a photo using the system camera, I move it into an album using MediaLibrary. Afterwards I want to display the photo in the application but the new file is not contained inside the asset array of getAssetsAsync.

This is my code:

const result = await ImagePicker.launchCameraAsync({});
if(!result.cancelled) {
  const cachedAsset = await MediaLibrary.createAssetAsync(result.uri);
  const album = await MediaLibrary.getAlbumAsync(constants.gallery_name);
  if(album === null) {
    MediaLibrary.createAlbumAsync(constants.gallery_name, cachedAsset, false);
  } else {
    MediaLibrary.addAssetsToAlbumAsync([cachedAsset], album, false);
  }

  const assetResult = await MediaLibrary.getAssetsAsync(
    {first: 1, album: album, sortBy: MediaLibrary.SortBy.creationTime});
  const asset = assetResult.assets[0];

  navigation.navigate('EditImage', {
    uri: asset.uri,
    type: 'image',
  });
}

Is there a way to force the MediaLibrary to recognize the new file immediately?
Or alternatively, get the new asset after it was moved into the album?

#2

Hey @dfels,

The new file isn’t appearing because you are not waiting for the createAlbumAsync or addAssetsToAlbumAsync methods to finish. You need to use await with them and handle their responses accordingly.

Here are the changes needed:

      const cachedAsset = await MediaLibrary.createAssetAsync(result.uri);
      const album = await MediaLibrary.getAlbumAsync(constants.gallery_name);
      if (album === null) {
        let albumCreated = await MediaLibrary.createAlbumAsync(
          constants.gallery_name,
          cachedAsset,
          false
        );
        if (albumCreated) {
          this.getAssetFromAlbum(albumCreated);
        } else {
          //handle album creation error
        }
      } else {
        let assetAdded = await MediaLibrary.addAssetsToAlbumAsync(
          [cachedAsset],
          album,
          false
        );
        if (assetAdded === true) {
          this.getAssetFromAlbum(album);
        } else {
          // handle asset add error
        }
      }
    }
  };

  getAssetFromAlbum = async album => {
    const assetResult = await MediaLibrary.getAssetsAsync({
      first: 1,
      album: album,
      sortBy: MediaLibrary.SortBy.creationTime,
    });
    const asset = await assetResult.assets[0];
  };

Cheers,

Adam

#3

Hi @adamjnav,

thank you but unfortunately it still behaves the same with your updated code.
getAssetFromAlbum doesn’t return the newly taken photo but one asset before that.

#4

Hmm. I had it working properly with that code in a Snack earlier. Can you create a Snack with your code?

#5

Here you are: https://snack.expo.io/H1Jdiik8X
I think you have to run it on a device, for me the camera app does not open in Snack.

This happens on my phone:

  • photo #1: correct picture is displayed (if the gallery was just created, otherwise the newest picture before photo #1 shows up)

  • photo #2: photo #1 shows up

  • photo #3: photo #2 shows up

  • and so forth

Best regards,
Daniel

#6

I’m getting the newest photo to display every time I take a picture. I’m running it on an iPhone 7 on the latest iOS. What device are you using?

#7

I am running it on an OnePlus 3 with Android 8.0.0, OxygenOS 5.0.4

#8

Alright, I just tested it on my Galaxy S8 and I’m getting the same behavior you described so it looks like it’s an Android bug. Can you create a Github issue on our expo repo detailing the issue and add your Snack there? https://github.com/expo/expo/issues

Thanks!

#9

Ok, I will do so.
Thank you for your support!

Edit: GitHub issue

1 Like
#10

Little update:
If I use createAlbumAsync also if the album already exists, everything works as intended.

closed #11

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.