Как разрешить пользователям загружать фото в приложение, созданное с помощью ИИ (и не сломать его)
Чтобы добавить загрузку фото в приложение, созданное с помощью ИИ, нужно хранить файлы в отдельном файловом хранилище (не в базе данных), задать ограничение на размер и тип файла — например, 10 МБ — и генерировать небольшое превью-изображение. Это основные инструкции, которые стоит дать своему билдеру.
В момент, когда ваше приложение перестаёт быть просто текстом и начинает позволять людям загружать фото, кое-что меняется. Добавление загрузки изображений и файлов означает, что пользователь может отправить фото, чек или документ со своего устройства в приложение, которое сохраняет его и потом показывает снова — фото профиля, чек, снимок повреждённой посылки, PDF-договор. Это одна из тех функций, которая выглядит как один переключатель, а на деле оказывается с несколькими острыми углами. Ни один из них не сложен сам по себе. Но те, о которых никто не предупреждает, обычно всплывают через три недели после запуска — как правило, у самого увлечённого вашего пользователя.
Это обзор того, что на самом деле происходит, когда кто-то нажимает «загрузить», трёх ошибок, которые аукаются позже, и точных формулировок, которые стоит дать своему билдеру, чтобы их избежать.
Что на самом деле происходит, когда вы загружаете фото в приложение?
Загрузка фото запускает четыре шага по порядку: телефон передаёт файл приложению, приложение отправляет его в отдельное файловое хранилище (не в базу данных), приложение сохраняет ссылку на этот файл рядом с записью, а позже, когда кто-то хочет посмотреть запись, приложение забирает файл по этой ссылке.
Вот как это выглядит по шагам:
- Телефон передаёт файл приложению. Современное фото с телефона часто весит от 4 до 12 мегабайт. Это не мелочь.
- Приложение отправляет этот файл куда-то на хранение — не в базу данных приложения, а в отдельное хранилище, созданное специально для файлов.
- Приложение сохраняет в базе данных ссылку на этот файл, рядом с остальной записью (этот чек относится к этому расходу).
- Позже, когда кто-то открывает запись, приложение забирает файл из хранилища по этой ссылке и показывает его.
Ошибку обычно допускают на шагах 2 и 3. Люди представляют, что фото «сохраняется в приложении». Это не так, и не должно быть так. Файлы живут в хранилище; база данных лишь запоминает, где именно. Разделите это правильно — и всё остальное станет проще.
Стоит ли хранить загруженные фото прямо в базе данных?
Нет — и это самая частая ошибка при загрузке файлов, которую ИИ-билдеры иногда допускают по умолчанию, если вы не указали иное. Запихнуть фото на 10 МБ прямо в базу данных — всё равно что хранить мебель в кошельке. База данных создана для небольших структурированных вещей — имён, дат, цен. Залейте в неё фотографии — и всё замедлится, резервные копии раздуются, а однажды страница, которая раньше открывалась мгновенно, начнёт грузиться шесть секунд, потому что тащит за собой сотню изображений в полном разрешении.
Что нужно вместо этого: файл уходит в файловое хранилище (ваш билдер может называть его «storage bucket» или «blob storage»), а база данных хранит только ссылку. Так и попросите:
«Храни загруженные изображения в файловом хранилище, а не в базе данных. В записи оставляй только URL файла».
Как не дать пользователям загружать не тот тип файла или слишком большой файл?
Вы заранее решаете, что разрешено — тип файла, ограничение по размеру и понятное сообщение об ошибке — и явно сообщаете об этом билдеру, потому что без этих правил приложение будет принимать что угодно, включая файлы, которые заставят загрузку зависнуть намертво. Два реальных случая показывают почему — и оба из приложений, которые прекрасно работали при тестировании.
Женщина, у которой небольшой кейтеринговый бизнес, сделала приложение, чтобы клиенты загружали фото понравившихся тортов. Всё работало отлично, пока один клиент не загрузил фото на 47 МБ прямо с профессиональной камеры. Загрузка зависла, клиент бросил попытку, а до неё это дошло как «ваше приложение сломано». Оно не было сломано — просто нигде не стояло ограничение по размеру, и приложение бесконечно пыталось проглотить огромный файл.
Второй случай: фрилансер сделал клиентский портал, куда люди загружают «свой логотип». Один клиент загрузил файл .zip. Другой — PDF на 90 страниц. Приложение приняло всё, потому что никто не сказал ему, каким должен быть логотип.
Решите заранее три вещи:
- Какие типы файлов? Только фото? Тогда принимайте JPG и PNG, а остальное отклоняйте с дружелюбным сообщением.
- Насколько большой? Разумное ограничение для фото — примерно 5–10 МБ. Достаточно для реального фото с телефона, но мало для дампа с камеры.
- Что если файл не тот? Приложение должно сказать об этом мягко — «Пожалуйста, загрузите JPG или PNG размером до 10 МБ», — а не просто зависнуть.
Скажите билдеру:
«Разреши загружать только изображения JPG и PNG размером до 10 МБ. Если кто-то загружает что-то другое или слишком большое, покажи понятное сообщение вместо того, чтобы молча падать».
Почему приложение начинает тормозить, когда в нём много фото?
Потому что каждый, кто просматривает запись, каждый раз скачивает полноразмерный оригинал, а не уменьшенную копию — на свой телефон, по своему мобильному интернету, каждый раз заново, когда кто-то открывает запись. Допустим, кто-то загрузил чёткое фото на 8 МБ, и само по себе оно работает нормально. Умножьте это на галерею из двадцати фото — и ваше быстрое маленькое приложение начинает буксовать, как в грязи.
У решения есть название, которое стоит знать, потому что билдер его узнает: миниатюра, или уменьшенная версия. Идея в том, что оригинал остаётся, но дополнительно создаётся небольшая веб-версия — и именно её показывают в списках и превью. Полная версия загружается только тогда, когда кто-то действительно хочет посмотреть фото крупно.
«При загрузке изображения также создавай уменьшенную версию для превью и списков. По умолчанию показывай уменьшенную версию и загружай полное изображение только тогда, когда кто-то нажмёт, чтобы посмотреть его крупно».
Вам не нужно понимать, как именно это делается. Нужно просто знать, что такая возможность существует, — чтобы попросить о ней до того, как приложение начнёт тормозить, а не после.
Ещё несколько менее заметных вещей, которые стоит решить
Эти три решения не сломают приложение, если их пропустить, но принять их сейчас дешевле, чем переделывать потом: кто может видеть файл, что происходит с ним при удалении записи и работает ли загрузка с телефона.
- Кто может видеть файл? Фото профиля можно показывать всем. Скан документа или подписанный договор — нет. Если файл приватный, скажите билдеру, что доступ по ссылке должен требовать входа в систему, а не быть публичным URL, который может открыть кто угодно. Это тот пункт, на котором я настаивал бы сильнее всего, если речь о чём-то чувствительном.
- Что происходит при удалении записи? Если кто-то удаляет расход, должно ли вместе с ним удаляться и фото чека? Иначе вы постепенно накапливаете «осиротевшие» файлы, за хранение которых платите и о существовании которых уже забыли.
- Работает ли это с телефона? Большинство загрузок происходит с телефонов, а телефоны предлагают и «сделать фото прямо сейчас», и «выбрать из галереи». Проверьте оба варианта на настоящем телефоне, а не только на ноутбуке, где вы просто перетаскиваете файл мышкой.
Протестируйте это так, как это сделал бы посторонний человек
Протестируйте это, намеренно пытаясь сломать так, как это случайно сделает настоящий пользователь — обычное фото, слишком большой файл, не тот тип файла, загрузка прямо с камеры телефона и удаление записи, — прежде чем считать задачу выполненной:
- Загрузите обычное фото с телефона. Появляется ли оно, и быстро ли грузится превью?
- Загрузите что-нибудь огромное. Останавливает ли приложение вас понятным сообщением, или просто зависает?
- Загрузите не тот тип файла — PDF там, где ожидается фото. Объясняет ли приложение правило?
- Откройте приложение на телефоне и загрузите фото прямо с камеры.
- Удалите запись и проверьте, обошлось ли с её файлом так, как вы решили заранее.
Если все пять пунктов ведут себя как надо — вы прошли те острые углы, на которых спотыкается большинство.
Загрузки — одна из тех функций, где разрыв между «работает в демо» и «работает у постороннего человека в поезде с фото кота на 12 МБ» — это ровно тот набор решений, что описан выше. Ни одно из них не сложное. Их просто легко пропустить — а попросить о них сейчас гораздо проще, чем чинить потом.
Если вы откладывали добавление загрузок, потому что это казалось большим техническим шагом, — это не так. Откройте своего билдера, попросите хранилище изображений с ограничением по размеру и миниатюрами — и посмотрите, что он вам даст. А потом попробуйте сломать это на своём телефоне — вот настоящий тест, и он займёт пять минут.