В рамках моего завершающего проекта на буткемпе по кодированию моя команда решила использовать Firebase в качестве серверной части. Создавая мобильное приложение для социальных сетей, нам нужен был хороший способ заполнить наш Cloud Firestore фиктивными пользовательскими данными и одновременно создать пользователей в Firebase Authentication с фиктивными учетными данными для входа. Хотя можно было вручную создать пользовательский документ в Cloud Firestore и ввести данные в документ, у нас было несколько полей, связанных с каждыми пользовательскими данными. Если бы мы хотели раздать более 100 пользователей, это заняло бы у нас много времени. Кроме того, почему бы не автоматизировать процесс? Ведь все мы инженеры-программисты!

Давайте начнем с рассмотрения того, что такое Firebase и Cloud Firestore.

Firebase — это платформа Backend-as-a-Service (BaaS), используемая для создания мобильных и веб-приложений. Сервис разработан и принадлежит Google. Он также управляет серверами вашего приложения, API и базой данных. Cloud Firestore — одна из функций, предлагаемых Firebase — это гибкая, масштабируемая облачная база данных NoSQL, которая хранит данные в документах и ​​коллекциях. В этой статье мы будем использовать Cloud Firestore для заполнения наших пользовательских данных.

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

Теперь для сценария заполнения потребуется файл конфигурации Firebase, который включает ваши настройки Firebase, такие как ключ API, домен аутентификации и URL-адрес базы данных.

К счастью, Firebase предоставляет многочисленные методы, которые вы можете использовать для упрощения разработки, одним из которых является .createUserWithEmailAndPassword(). Этот метод принимает в качестве параметра адрес электронной почты и пароль (если вы еще не догадались по имени) и создает новую учетную запись пользователя, связанную с указанным адресом электронной почты и паролем. Поскольку этот метод является частью службы аутентификации Firebase, нам нужно связать метод с firebase.auth() для правильного использования. Метод возвращает обещание, которое содержит учетные данные пользователя, такие как уникальный идентификатор пользователя (uid), адрес электронной почты, метаданные и многое другое. Среди них нам действительно нужен uid, чтобы мы могли создать пользовательский документ с тем же uid, что и ссылка на документ. Когда Promise успешно разрешается, мы можем использовать ответ для создания пользовательского документа со сгенерированным uid и заполнить документ каждым из наших исходных пользовательских данных, используя метод .set() FireStore.

При тестировании нашего кода мы столкнулись с первой ошибкой! Это ожидаемо в программировании. Нет пота.

Firebase смогла массово создать пользователей в Authentication, но только один из исходных пользователей был добавлен в Firestore в качестве пользовательского документа. Изучив документацию Google, Stack Overflow и Firebase, мы узнали, что это действительно ожидаемое поведение Firebase. Если пользователь создан методом .createUserWithEmailAndPassword() с аутентификацией, вновь созданный пользователь становится текущим пользователем приложения. Это означает, что Firebase обнаружил изменение пользователя, в результате чего Firebase закрывает все ожидающие потоки и отменяет все дальнейшие запросы!

Это натолкнуло меня на мысль: если мы массово создаем пользователей и автоматически входим в систему, должен быть способ автоматически выводить их из системы, верно? Без сомнения, мы нашли метод Firebase, который выходит из системы текущего пользователя: .signOut(). Теперь мы можем продолжить цикл создания нового пользователя, входа в систему, создания пользовательского документа в Firestore и выхода из него.

Конечно, использование только метода .signOut не решило проблему. Мы столкнулись с еще одним препятствием: последовательное выполнение асинхронного кода внутри циклов было сложным. На самом деле циклы for в JavaScript (включая методы .forEach и .map) не ждут завершения выполнения асинхронного кода перед переходом к следующей итерации цикла.

После попытки заполнить базу данных с помощью обычного цикла for, методов .forEach и .map и неоднократно сталкиваясь с одной и той же ошибкой, я решил поискать в другом месте. В конце концов, наша команда хотела выполнить набор асинхронных функций в последовательном порядке. Хм… как мы можем последовательно повторять код? Подождите, кто-то сказал setInterval()?

Оказывается, нативная функция JavaScript setInterval() идеально подходит для нашей цели. По сути, метод setInterval() выполняет предоставленный фрагмент кода функции с заданной временной задержкой между каждым вызовом функции.

Время задержки 2000 мс (2 секунды) является произвольным — я сделал обоснованное предположение, что вся последовательность эффективных вызовов Firebase займет менее 2 секунд. Мы попробовали, и…

Вуаля! Использование setInterval() отлично сработало для нашей цели заполнения, выполняя несколько операций Firebase по добавлению пользователя в аутентификацию, созданию пользовательского документа в нашей коллекции пользователей, выходу пользователя — все в правильном последовательном порядке.

Ниже приведен полный, окончательный код с комментариями для облегчения понимания:

Использование методов .signOut и setInterval() было одним из способов заполнения Cloud Firestore, и я уверен, что есть разные способы достижения одной и той же цели. Пожалуйста, не стесняйтесь поделиться своим подходом в комментариях ниже — я буду рад это услышать. Спасибо за чтение и счастливого посева! 🌱