Всем привет. Меня зовут Алессандро, и это моя самая первая история на Medium. Я очень рад быть писателем здесь, так что давайте начнем, так как сегодня у меня есть кое-что очень интересное для вас.

Необходимая предпосылка: я Frontend и мобильный разработчик, и мне очень нравится экосистема Flutter. Я думаю, что в настоящее время это должен знать каждый мобидев. Тем не менее, более выигрышная комбинация, безусловно, Firebase + Flutter: черт возьми, ребята из Google никогда не ошибаются в этом смысле. Им удалось предоставить замечательный продукт для разработчиков-одиночек (которые не несут никаких затрат), при этом присматривая за крупными компаниями (которые могут тратить много денег). Все победители! Ура!

Пойдем устроим вечеринку, хорошо? Ну нет. По крайней мере, не с этим духом. Даже если Firebase — отличный инструмент, а его плагины Flutter действительно хорошо разработаны и документированы (черт возьми, хорошо документированный продукт Google??? 😱 😱 😱), некоторые реализации немного утомительны и не очень удобны для разработчиков.

Просто для ясности: все это мое личное мнение, это результат моих проблем и решений за 6 лет моей мобильной разработки, и вы можете не соглашаться. Это меня устраивает. Просто не забудь быть добрым, если ты не согласен со мной, хорошо? 😉

FIREBASE STORAGE: Господи, какой замечательный инструмент. Это позволяет вам архивировать ваши файлы, а затем обслуживать их с помощью долгоживущей ссылки, которая обновляется с помощью токена, так что попрощайтесь со всеми старыми проблемами кеша Google Cloud Storage. Да, это правда, но способы получения доступа к этим ресурсам, на мой взгляд, слишком сложны. Вы сохраняете файл внутри FCS, затем из своего клиентского приложения вы должны запросить ссылку для скачивания (и это будущее, которое следует ожидать). Затем у вас есть ссылка для скачивания… и снова будущее, чтобы загрузить видео/показать свое изображение/получить доступ к вашему ресурсу. А что делать, если вы хотите получить его снова? Вы угадали! Это снова Будущее Будущего Будущего… О боже, я становлюсь старше!

Не лучше ли иметь что-то, что управляет этой асинхронностью, оставляя нам только удовольствие от доступа к ней?

Представляем CACHED FIRESTORAGE



Как говорится, Cached Firestorage — это утилита, которая решает нашу проблему, кэшируя URL-адреса загрузки FCS и удаляя слой сложности внутри кода Dart. Он также предоставляет виджет, оптимизированный для умного отображения изображений. О, и это написано в Dart 2.17 — Flutter 3.0. Красиво, верно? 😃

Перво-наперво, давайте выберем тайм-аут кеша. Выражается в минутах.

CachedFirestorage.instance.cacheTimeout = 30;

Вы не обязаны этого делать: значение по умолчанию установлено на 360 минут (6 часов). На этом этапе вы можете получить доступ к своему ресурсу с помощью следующего фрагмента кода:

FutureBuilder<String>(
  future: CachedFirestorage.instance.getDownloadURL(
    mapKey: '1',
    filePath: '1.jpeg',
  ),
  builder: (_, snapshot) =>
      snapshot.connectionState == ConnectionState.waiting
          ? const CircularProgressIndicator.adaptive()
          : snapshot.hasError
              ? const Text('An error occurred')
              : Image.network(
                  snapshot.data!,
                  height: 100,
                ),
)

Видеть? С одним FutureBuilder я запросил URL-адрес загрузки, который был кэширован. С этого момента и до истечения срока действия кеша каждый раз, когда вы запрашиваете «1.jpeg», URL-адрес загрузки будет немедленно извлекаться, что сокращает время ожидания.

«А что, если одна и та же ссылка меняет содержание?» Давайте представим, что я указываю на что-то вроде «images/{userId}/profile.png». Если пользователь обновит изображение своего профиля, у меня всегда будет старая ссылка для скачивания в памяти, и мне придется ждать истечения срока действия кеша!

Вы правы, на самом деле Cached Firestorage предоставляет метод для ручного аннулирования кеша для одного элемента:

String currentPic = '2-1.jpeg';
FutureBuilder<String>(
  future: CachedFirestorage.instance.getDownloadURL(
    mapKey: '2',
    filePath: currentPic,
  ),
  builder: (_, snapshot) =>
      snapshot.connectionState == ConnectionState.waiting
          ? const CircularProgressIndicator.adaptive()
          : snapshot.hasError
              ? const Text('An error occurred')
              : Image.network(
                  snapshot.data!,
                  height: 100,
                ),
),
ElevatedButton(
      child: const Text(
        'Remove cache + Change URL',
        style: TextStyle(fontSize: 12),
        textAlign: TextAlign.center,
      ),
      onPressed: () {
        setState(() {
          currentPic =
              currentPic == '2-1.jpeg' ? '2-2.jpeg' : '2-1.jpeg';
          CachedFirestorage.instance.removeCacheEntry(mapKey: '2');
        });
      },
)

Замечательно, правда? Но ЛУЧШЕЕ ЕЩЁ ПРИБЫЛО!

Написание всего этого кода для отображения изображения утомительно, верно? К счастью (нет, это не везение, это моя тяжелая работа 🤪 ) Cached Firestore поставляется со встроенным виджетом RemotePicture, оптимизированным именно для этой цели. Просто используйте его таким образом:

RemotePicture(
  imagePath: '3.jpeg',
  mapKey: '3',
)

И вуаля! Все управляется внутри! Вы также можете использовать его для отображения аватара:

RemotePicture(
  imagePath: 'avatar.jpeg',
  mapKey: 'avatar',
  useAvatarView: true,
  avatarViewRadius: 60,
  fit: BoxFit.cover,
)

Вот и все! Очень просто! Нет будущего, нет ожидания, нет шаблона! Просто выберите и используйте!

Заключение

Надеюсь, вам понравилась эта статья. Если это так, не забудьте похлопать и поделиться этим, где хотите! Удачного кодирования! 🙌🏻

Вы нашли мою статью полезной? Тогда можешь купить мне кофе!