Back

Images from Bucket aren’t loading right away on iPhones

  • 0
  • General
  • Web
  • Apple
  • Storage
kathelia.dokgu
15 Sep, 2023, 04:53

On my NextJS project I have a bunch of images saved on an Appwrite bucket and I have a document that contains the file ID to reference the bucket file. I would use that ID to get the file URL and I would use that URL as the src for my img element.

On desktop and Android devices, the images seem to load right away but on iPhones, they don’t show up on page load. I have to manually refresh the page before the images show up. Any idea? Has anyone encountered this before and know of a solution?

TL;DR
Images from an Appwrite bucket aren't loading immediately on iPhones. The issue seems to be specific to iPhones as the images load fine on desktop and Android devices. Reloading the page manually makes the images show up. No error logs are being captured by Sentry. The code provided shows the logic for displaying different media types. It seems that the issue might be related to how the images are being fetched from the bucket. The user is looking for potential solutions or if anyone has encountered this issue before. No solution is provided in the thread.
Drake
15 Sep, 2023, 20:20

is it possible to get any sort of logs from the device?

kathelia.dokgu
15 Sep, 2023, 20:50

I was planning on using Winston as my app's logger but I haven't gotten around to doing that yet. I use Sentry on my app so it should've captured the issue if there was an error. But with the lack of Sentry events being captured, I'm assuming no errors were encountered.

I have a Message component where I would pass an Appwrite document that contains a mediaId property which could either be a bucket file ID or null. On component mount, I would check if the mediaId is set and if it is, I would get the URL by using storage.getFileView(...):

TypeScript
useEffect(() => {
  const getFileData = async () => {
    if (message.mediaId) {
      try {
        // Get the mime type
        const fileInfo = await storage.getFile(Constants.APPWRITE_BUCKET_ID, message.mediaId);

        setMedia(fileInfo);
        setMimeType(fileInfo.mimeType.toLowerCase());

        if (fileInfo.mimeType.toLowerCase().startsWith('image')) {
          // Image
          const image = await storage.getFileView(Constants.APPWRITE_BUCKET_ID, message.mediaId);
          setFileView(image);
        } else if (fileInfo.mimeType.toLowerCase().startsWith('video')) {
          // Video
          const video = await storage.getFileView(Constants.APPWRITE_BUCKET_ID, message.mediaId);
          setFileView(video);
        } else {
          // Unknown (allow the user to download)
          const file = await storage.getFileDownload(Constants.APPWRITE_BUCKET_ID, message.mediaId);
          setFileView(file);
        }
      } catch (error: any) {
        setIsMediaError(true);
      }
    }
  };

  getFileData();
}, []);
kathelia.dokgu
15 Sep, 2023, 20:50

And then for the JSX this is what I do:

TypeScript
{message.mediaId ? (
  <span
    className='flex justify-center items-center p-1 rounded-md rounded-br-none text-gray-800'
    style={{ backgroundColor: `${room.color}33` }}>
    {mimeType && mimeType.startsWith('image') && fileView ? (
      <img
        src={fileView.href}
        className='max-w-full max-h-full object-contain'
      />
    ) : mimeType && mimeType.startsWith('video') && fileView ? (
      <video
        className='video-player'
        controls
        preload='metadata'
        playsInline={true}>
        <source src={fileView.href} type={mimeType} />
        Your browser does not support the video tag
      </video>
    ) : media && mimeType && fileView ? (
      <Link
        href={fileView.href}
        download={true}
        className='flex items-center gap-x-3 rounded-md overflow-x-hidden px-3 py-2 text-sm font-semibold outline-none truncate text-white shadow-sm'>
        <CloudArrowDownIcon
          className='-ml-0.5 h-5 w-5 shrink-0'
          aria-hidden='true'
        />
        <span className='text-left'>
          <span>Download</span>
          <span className='block font-light text-xs text-gray-100 truncate whitespace-normal'>
            {media.name}
          </span>
        </span>
      </Link>
    ) : isMediaError ? (
      <button
        type='button'
        className='flex items-center gap-x-3 rounded-md overflow-x-hidden px-3 py-2 text-sm outline-none truncate text-white shadow-sm'>
        <ExclamationCircleIcon
          className='-ml-0.5 h-5 w-5 shrink-0'
          aria-hidden='true'
        />
        <span className='text-left'>
          <span>The file could not be found.</span>
        </span>
      </button>
    ) : (
      <Spinner size='md' />
    )}
  </span>
) : (
  <span
    className='px-3 py-2 rounded-md inline-block rounded-br-none text-gray-800 whitespace-pre-wrap'>
    {message.message}
  </span>
)}
Drake
15 Sep, 2023, 20:57

Maybe something is null that you don't expect 🤷‍♂️

Reply

Reply to this thread by joining our Discord

Reply on Discord

Need support?

Join our Discord

Get community support by joining our Discord server.

Join Discord

Get premium support

Join Appwrite Pro and get email support from our team.

Learn more