В предыдущем посте мы узнали о том, как включить Firestore в консоли Firebase и интегрировать это с Actions on Google для масштабируемого хранения данных для нескольких пользователей Google Assistant на нескольких устройствах. В этом посте мы углубимся в Cloud Firestore, используя различные методы запросов. Мы сможем запрашивать несколько документов и сообщать пользователям, сколько из них больше всего планет, о которых они спрашивали чаще всего. Чтобы увеличивать число count каждый раз, когда задают вопрос о планете, мы обновим свойство count каждого документа.

Вот диалог, который вы создадите после прочтения этого сообщения в блоге:

Обновить документ

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

Шаг 1

Во-первых, нам нужно извлечь определение, слово и запись количества запросов из нашего документа в строке 19. Здесь важно отметить, что теперь мы отслеживаем количество запросов к планете, которого раньше не было в предыдущем коде.

Шаг 2

Давайте продолжим и обновим документ в базе данных, вызвав метод update. Вы можете спросить, зачем нам делать {count: count +1}. Здесь вам следует знать две вещи:

Мы передаем объект в метод обновления, который сообщает Firestore, что поля обновляются. В этом случае мы просто хотим обновить поле подсчета. Firestore не поддерживает возрастающие значения (например, count + = 1).

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

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

После добавления приведенного выше кода для увеличения счетчика вы можете использовать этот счет, создав новое намерение под названием ask_top_three_intent. В этом новом намерении мы рассмотрим различные методы запроса, такие как .where (), .orderBy () и .limit ().

Создать ask_top_three_intent

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

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

  1. Щелкните три точки, обведенные красным.

2. Выберите Значение по умолчанию.

3. Введите «3» в поле.

Запрос из нескольких документов

Теперь, когда вы создали ask_top_three_intent, давайте рассмотрим код.

В качестве основы документы в Firestore имеют следующую структуру:

У документов, хранящихся в нашей базе данных, есть два новых поля: количество и тип. Наша база данных содержит записи, описывающие планеты, звезды (солнце) и луну. Тип добавлен, чтобы помочь запросам найти документы, соответствующие сделанному запросу, в данном случае нам нужны только планеты. Поскольку эти другие записи не являются планетами, нам нужен способ отфильтровать их для ask_top_three_intent. Именно здесь вступает в игру новый тип поля .

Если вы внимательно посмотрите на строку 33, вы заметите, что мы вызываем метод where () и даем ему критерии фильтрации. Это указывает базе данных возвращать только те документы, которые классифицируются как планеты. Хотя это возвращает нам все планеты, нам все же нужно расположить их в порядке популярности, поэтому мы используем orderBy.

На данный момент мы создали запрос, который выбирает только планеты и ранжирует их в порядке популярности, но мы не ограничиваем количество возвращаемых документов. Чтобы ограничить количество возвращаемых документов, мы должны вызвать метод limit () и передать максимальное количество документов, которое мы хотим вернуть.

В отличие от получения одного документа, при запросе нескольких документов мы возвращаем объект QuerySnapshot, у которого есть свойство, называемое docs, как показано в строке 38.

Как вы, возможно, заметили, API запросов имеет множество способов, позволяющих настраивать результаты.

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

Что такое составной индекс?

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

Если вы запустите приведенный выше код, вы бы услышали в симуляторе «извините, я не могу подобрать вам три верхних слова». Хорошо, что пошло не так и как нам узнать? Первое, что вы всегда должны делать, когда сталкиваетесь с ошибкой, - это просматривать журналы Firebase. Ниже приведен снимок экрана с сообщением об ошибке, с которым я столкнулся:

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

После перехода по URL-адресу вы увидите всплывающее диалоговое окно, показанное ниже. Используйте это для создания составного индекса по двум полям: тип и количество. Причина, по которой мы видим всплывающее диалоговое окно, заключается в том, что у нас есть предложение where для type == ‘planet’, и мы упорядочиваем по убыванию счетчика!

Вы можете узнать больше о том, зачем нужны составные индексы, посмотрев Как работают запросы в Cloud Firestore замечательного Тодда Керпельмана

Создание индекса займет несколько минут, и во время его создания вы увидите слово «сборка».

Как только это будет завершено, вернитесь в симулятор. На этот раз вы услышите три верхние планеты, которые могут быть примерно такими:

Сатурн
Марс
Земля

Теперь, если мы проверим действие, запросив четыре верхние планеты, диалог будет выглядеть так:

Теперь вы узнали, как легко запрашивать Firestore! В дальнейшем вы можете использовать базу данных Firestore для создания новых действий. Использование Firestore особенно актуально, когда вы хотите создать что-то вроде таблицы лидеров для голосовой игры или любого действия, которое требует хранения данных для нескольких пользователей на разных устройствах.

Вы можете найти весь код файла index.js здесь как Суть. Если вы заинтересованы в изучении некоторых более продвинутых диалоговых функций, таких как Helper Intents и SSML, посмотрите запись Systers Workshop 2 здесь.

Кроме того, вы можете найти список ресурсов здесь, включая Действия в Google Codelabs Level 1 & 2. Если вы новичок в Actions on Google, я рекомендую посмотреть запись Systers Workshop 1 здесь. Поделитесь с нами своими достижениями, написав в Твиттере #AoGDevs и подписавшись на @ActionsOnGoogle!