Практика создания упрощенного «клона» Google Keep с нуля

Я фанат Google Keep, пользуюсь им с момента его запуска. Я помещаю отложенные задачи, напоминания о делах и почти все, что нужно запомнить, в Keep. Он интуитивно понятен в использовании, помогает мне сосредоточиться на приоритетах.

Поскольку я создавал приложения Flutter в течение последних двух лет, я думаю, что было бы интересно создать приложение для блокнотов, такое как Keep, с нуля.

Так называемое приложение «Flutter Keep», которое я сделал до сих пор, выглядит так:

Я собираюсь рассказать об этом процессе в серии статей. Ключевые компоненты будут добавляться в приложение во время итераций, чтобы облегчить понимание.

В этой первой части серии мы собираемся настроить проект Flutter, предоставить процесс аутентификации и простой экран для отображения списка заметок.

Давайте начнем.

Перед созданием проекта вы можете включить веб-поддержку с помощью команды: flutter config -- enable-web, если вы хотите, чтобы приложение могло работать в Интернете помимо Android и iOS.

Теперь выполните команду: flutter create flt_keep, чтобы создать приложение Flutter Keep, flt_keep - это имя пакета, которое будет использоваться в операторах импорта.

Для тех, кто плохо знаком с Flutter, следуйте Руководству по началу работы, чтобы установить SDK и ознакомиться со структурой проекта.

Структура данных

Для приложения для записной книжки первое, что нужно учитывать, - это то, как следует сохранять и запрашивать заметки.

То, что меня беспокоит, включает:

  • Во-первых, конфиденциальность. Заметки разных счетов должны быть отделены друг от друга.
  • Во-вторых, приложение должно работать в автономном режиме. Пользователи должны иметь возможность делать заметки в любых условиях сети. Приложение несет ответственность за синхронизацию данных при восстановлении сетевого подключения.

Я выбрал Cloud Firestore, в основном из-за опыта, накопленного мною в предыдущих проектах, но также и потому, что его легко перенять.

Я решил использовать специальную коллекцию для хранения заметок каждого пользователя, один документ для одной заметки. По причинам:

  • Лучшее разделение данных каждой учетной записи
  • Легко запросить
  • Избегает некоторых ограничений при чтении и записи данных

Этот подход также требует затрат, но он приемлем для демонстрационных целей. То есть мне нужно динамически создавать индексы для каждой коллекции, я расскажу об этом в одной из следующих статей.

На данный момент структура данных такая:

Архитектура приложения

Пришло время подумать, как организовать логику приложения. Не стоит применять «настоящую» архитектуру к приложению в основном для демонстрации. Но по-прежнему необходимо управлять состояниями на нескольких экранах в приложении.

В этом случае мы собираемся использовать пакет provider для управления состоянием приложения. Это позволяет нам писать код в реактивном (или управляемом данными) стиле.

Наиболее важные экраны в приложении включают:

  • Экран аутентификации, отслеживающий состояние входа, гарантирует, что только аутентифицированные пользователи могут делать заметки
  • Экран списка заметок, отображающий самое последнее состояние заметок, должен реагировать на изменения любой заметки.
  • Редактор заметок также должен реагировать на внешние изменения конкретной редактируемой заметки.

С помощью провайдеров мы можем легче выполнить вышеуказанные требования с более чистой кодовой базой.

Имея в виду схему, приступим к написанию кода.

Чтобы использовать provider и SDK Firebase, мы должны добавить зависимости в файл pubspec.yaml:

provider: ^4.0.2
firebase_core: ^0.4.4
firebase_auth: ^0.15.4
cloud_firestore: ^0.13.3
google_sign_in: ^4.1.4

Пожалуйста, следуйте подробным инструкциям, чтобы интегрировать Firebase SDK как для Android, так и для iOS, а также Веб-платформу.

Вход в приложение

Помните, что мы должны отклонять неаутентифицированных пользователей, давайте создадим виджет привратника в корень.

Пара _6 _ / _ 7_ здесь предназначена для наблюдения за onAuthStateChanged, потоком событий аутентификации Firebase, всякий раз, когда состояние входа изменилось, Consumer получит уведомление и перестроит виджет в соответствии с текущим состоянием.

Небольшая хитрость заключается в том, чтобы использовать CusttentUser для обертывания FirebaseUser, чтобы различать начальное состояние по умолчанию и состояние без аутентификации, оба из которых - null.

Вход в Google и аутентификация в Firebase

В качестве примера я использую вход через Google, потому что его легко интегрировать. Фактически, это лишь одна из многих служб, поддерживаемых Firebase Auth. Вы можете включить все, что вам нужно, в консоли Firebase.

Фрагмент кода для аутентификации с помощью входа в Google:

Просто запросите учетные данные для входа в Google, а затем используйте их для аутентификации в Firebase.

Как видите, после успешного завершения аутентификации делать нечего. В этой ситуации поток FirebaseAuth.onAuthStateChanged генерирует событие «Выполнен вход», которое запускает повторную сборку корневого виджета привратника, чтобы отобразить HomeScreen.

Выше приведен пример Реактивного программирования: просто измените состояние, и слушатели, которые беспокоятся о состоянии, выполнят оставшуюся работу.

Вернувшись к проекту, перед тестированием экрана входа убедитесь, что вы не игнорируете следующие настройки:

Запросы примечаний

Теперь, когда пользователь прошел проверку подлинности, мы можем перейти на главный экран приложения - список заметок.

Но как добавить первую заметку без редактора заметок? Вы можете сделать это с помощью консоли Firebase:

Назовите коллекцию notes-{user_id}, и вы можете найти свой идентификатор пользователя на странице Проверка подлинности консоли Firebase.

Чтобы усилить безопасность конфиденциальности, вы также можете установить правила доступа для набора данных, убедившись, что пользователи могут видеть и редактировать только свои собственные заметки.

Прежде чем мы сможем получить заметки из Firestore, нам понадобится модель, которая представляет отдельную заметку, и функции для преобразования между моделью Firestore и нашей собственной.

Мы снова собираемся использовать StreamProvider в HomeScreen, который отслеживает результат запроса примечаний, чтобы любые изменения, происходящие с серверной частью, мгновенно отражались здесь. Firestore SDK также предоставляет необходимые нам автономные возможности, нам не нужно изменять код, используемый для доступа к данным.
И спасибо за созданный ранее виджет gatekeeper, который позволяет нам в любое время получить информацию для аутентификации через Provider.of<CurrentUser>.

Код немного многословен, потому что я привожу здесь плавающий AppBar, похожий на тот, что есть в Google Keep.

Для NotesGrid и NotesList они очень похожи: просто своего рода оболочка для SliverGrid и SliverList соответственно.

Я не публикую здесь подробный код. Полный пример можно найти в моем репозитории на GitHub.

Если все пойдет хорошо, теперь вы сможете увидеть первую заметку в своем самодельном приложении Flutter Keep!

Пока у нас все хорошо. Мы создали простое приложение в реактивном стиле с помощью пакета provider, а также узнали, как использовать наборы инструментов Firebase.

Однако приложение бесполезно без редактора заметок. Мы добавим к нему больше функций в следующих частях серии.

Спасибо за чтение! 🙌