Как получить все необходимые данные от одного пользователя в боте диалогового потока и сохранить их в firestore под одним идентификатором пользователя - PullRequest
0 голосов
/ 29 июня 2018

Мой пример кода index.js для сохранения только имени:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
let action = request.body.result.action;
var Name = request.body.result.parameters.Name;
let query = request.body.result.resolvedQuery;
const parameters = request.body.result.parameters; 
const inputContexts = request.body.result.contexts; 
if(action === 'save.name' || inputContexts == 'welcome'){
        admin.firestore().collection('users').add({
        name: Name
        }).then(ref => {
        console.log('Added new user');
       });    
    } 
 });   

Сейчас я реализовал сохранение имени отдельно и сохранение других деталей отдельно, но проблема в том, что все хранится в отдельных идентификаторах пользователя в firestore, Я хочу, чтобы все данные одного пользователя были сохранены в одном userId

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

Я использую бот api v1

1 Ответ

0 голосов
/ 29 июня 2018

В общем, вам нужно обновить документ, хранящийся в Firestore, для каждого намерения, которое доставляет вам данные. Вы можете сделать это с docRef.update().

Хитрость в том, что при создании документа вам нужно будет сохранить способ вернуть документ позже, чтобы обновить его. Это требует двух вещей:

  1. Вам необходимо либо создать документ с известным идентификатором, либо получить идентификатор, назначенный системой.

  2. Затем вы сохраняете это в контексте диалогового потока и извлекаете его из контекста при следующей обработке намерения.

Мы будем использовать идентификатор пользователя для нескольких вещей, поэтому мы можем объявить его сверху.

var userId; // We'll use this for a few things

При создании документа возвращаемое ref имеет поле id, содержащее идентификатор добавленного документа.

admin.firestore().collection('users').add({
  name: Name
}).then(ref => {
  userId = ref.id;
  console.log('Added new user with id '+userId);
});

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

var outputContext = [
  {
    name: "user_information",
    lifespan: 5,
    parameters: {
      id: userId
    }
  }
];

responseObject = {
   // ...
   outputContext: outputContext
};

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

var getIdFromRequest = function( request ){
  var id;
  var contexts = request.body.result.contexts;
  for( var co=0; co<contexts.length; co++ ){
    var context = contexts[co];
    if( context.name === 'user_information' ){
      id = context.parameters.id;
    }
  }
  return id;
}

При обработке Intent вы получите идентификатор с

userId = getIdFromRequest( request );

Когда мы перейдем к добавлению данных, мы создадим объект, добавим к нему параметры, а затем обновим документ этим новым объектом. (Этот код не самый эффективный способ, но по логике это будет примерно так)

var updateObj = {};
if( parameters.color ){
  updateObj.color = parameters.color;
}
if( parameters.pet ){
  updateObj.pet = parameters.pet;
}
if( parameters.age ){
  updateObj.age = parameters.age;
}

admin.firestore().collection('users').doc(userId).update( updateObj )
  .then( ref => {
    console.log('User updated');
  })
  .catch( err => {
    console.error.( 'Something is wrong', err );
  };
...