Javascript Firebase Firestore函数未执行 [英] Javascript firebase firestore function not executing

查看:73
本文介绍了Javascript Firebase Firestore函数未执行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用ActionsSDK,Firebase Functions和Firebase Firestore构建ActionsOnGoogle App。

i try to build a ActionsOnGoogle App with the ActionsSDK, Firebase Functions and Firebase Firestore.

我构建了具有意图的实现。启动Actions App时的mainIntent,以及用户从mainIntent回答问题时的answerIntent。从firestore数据库中获取mainIntent中的文本,并要求带有包装文本的用户工作得很好。但是,在从数据库数组中包装新数据的函数内部,就被填充了。执行此函数后,数组ist为空。

I build a fulfillment that haves to intents. The mainIntent when starting the Actions App and the answerIntent when the users answers the question from the mainIntent. Getting the text in the mainIntent from the firestore database and ask the users with the wrapped text work very fine. But then inside the function where new data is wrapped from the database array get filled. After executing this function the array ist empty.

这是我的代码:

    function answerIntent(app){
    console.log('DEBUG: answerIntent acsess');
    console.log('DEBUG: ' + partAwnserRef);

    var rawInput = app.getRawInput();

    var answerCollection = db.collection(partAwnserRef);
    var answers = answerCollection.get().then(collection => {
      console.log('DEBUG: Collection size: ' + collection.size);
      collection.forEach(document => {
        if(document.exists){
          console.log('DEBUG: document ID: ' + document.id + ' = ' + document.data());
          answerDocumentArray.push(document);
          console.log('DEBUG: ArraySize: ' + answerDocumentArray.length);
          //HERE MY ARRAY WAS FILLED CORRECTLY
        }
        else{
          console.log('DEBUG: Dokument existiert nicht;');
          app.tell('Es liegt ein Fehler vor!');
        }
      });
    })
    .catch(err => {
      console.log('DEBUG: Es ist ein Fehler aufgetretten ' + err); 
      app.tell('Es liegt ein Fehler vor!');
    });

    //HERE THE OUTPOT IN THE LOG SAY THE ARRAY IS EMPTY
    console.log("DEBUG: lenght " + answerDocumentArray.length);

    for(var i = 0; i < answerDocumentArray.length; i++){
      var propertyNameArray = [];

      for(var propertyName in answerDocumentArray[i]){
        propertyNameArray.push(propertyName);
        console.log('DEBUG: propertyName: ' + propertyName);
      }

      for(var j = 0; j < propertyNameArray.length; j++){
        if(propertyNameArray[j].includes('answer')){
          if(rawInput.includes(answerDocumentArray[i].propertyNameArray[j])){
            app.tell(answerDocumentArray[i].propertyNameArray[j]);
          }
          else{
            var inputPrompt = app.buildInputPrompt(false, 'Ich habe die leider nicht verstanden!', ['Kannst du deine Antwort wiederholen?']);
            app.ask(inputPrompt); 
          }
        }
      }
    }
   };

当我查看Firebase日志时,看到的是我的自编码日志。我得到以下内容。最早的日志记录员。

When i look inside the firebase logs is see my self coded logs. And there i get the following. First log ist latest.


调试:长度为0

DEBUG: lenght 0

调试:收集大小:2

调试:文档ID:answer1 = [object Object]

DEBUG: document ID: answer1 = [object Object]

调试:ArraySize:1

DEBUG: ArraySize: 1

调试:文档ID:answer2 = [对象对象]

DEBUG: document ID: answer2 = [object Object]

调试:ArraySize:2

DEBUG: ArraySize: 2


推荐答案

您有两个问题,它们都从根本上涉及理解结果如何从您的工作中传回:

You have two problems, both of them fundamentally involve understanding how results get passed back from what you're working on:

问题1:处理承诺

原因<$ c $ DEBUG:长度行中的c> answerDocumentArray 为空是因为调用 answerCollection.get()实际上并不返回值。它返回一个JavaScript Promise对象,该对象最终将解析为这些值。

The reason answerDocumentArray is empty at the DEBUG: lenght line is because the call to answerCollection.get() does not actually return the values. It returns a JavaScript Promise object that will eventually resolve to the values.

直到这样做,它仍将继续执行代码,并且代码的下一行是

Until it does, however, it will keep executing the code, and the next line in the code is the debugging line.

当它确实解析为这些值时, then()子句中的函数将为被调用,并将开始处理返回的集合。但这可以在调试行之后的行之后执行。函数完成后,它应返回另一个Promise,其中包含指示需要进一步评估的结果。 (在这种情况下,您不会返回任何内容,结果将为空。)

When it does resolve to those values, the function in the then() clause will be called and will start processing the collection returned. But this may be executed after the lines following the debugging line. When the function completes, it should return another Promise with any results indicating what needs to be further evaluated. (In this case - you're not returning anything, which ends up as a null.)

您可能应该做的是再添加一个,然后()子句,将通过 answerDocumentArray 传递的第一个子句与之配合使用。大概是这样的:

What you should likely do is have another then() clause that chains off the first one that is passed the answerDocumentArray and works with it. Something roughly like this:

var answers = answerCollection.get().then( collection =>{
    console.log( 'DEBUG: Collection size: ' + collection.size );
    collection.forEach( document =>{
      if( document.exists
      ){
        console.log( 'DEBUG: document ID: ' + document.id + ' = ' + document.data() );
        answerDocumentArray.push( document );
        console.log( 'DEBUG: ArraySize: ' + answerDocumentArray.length );
        //HERE MY ARRAY WAS FILLED CORRECTLY
      }
      else{
        console.log( 'DEBUG: Dokument existiert nicht;' );
        app.tell( 'Es liegt ein Fehler vor!' );
      }
    } )
    return Promise.resolve( answerDocumentArray );
    ;
  } )
  .then( answers => {
    for( var i = 0; i < answers.length; i++ ){
      // ... Do stuff with the answers here
    }
  })
  .catch( err =>{
    console.log( 'DEBUG: Es ist ein Fehler aufgetretten ' + err );
    app.tell( 'Es liegt ein Fehler vor!' );
  } )
  ;

(我可能已经弄错了关于Promises的解释,但是请帮自己一个忙-学习JavaScript Promises。仍然很痛苦,但是它们使JavaScript回调的世界变得更加容易。)

(I may have mangled the explanation about Promises, but do yourself a favor - learn JavaScript Promises. They're still a pain, but they make JavaScript callbacks worlds easier.)

但是您对执行任务部分所做的工作却导致了第二个问题:

But what you do with the "do stuff" part... leads to the second problem:

问题2:通过Google上的操作返回值

此代码块尝试在一个循环中(实际上是在一个双循环中,但是即使一个循环也足够糟糕)将值返回给Google Assistant。

This code block attempts to return values to the Google Assistant inside a loop (actually, inside a double-loop, but even one loop is bad enough).

除非只能保证一个结果,否则您将尝试调用 app.ask() app.tell()不止一次,假设您可以为每个符合条件的文档返回一个响应。

Unless you can guarantee only one result, you're going to try and call either app.ask() or app.tell() more than once, assuming you can return one response for each document that matches the conditions that you meet.

for( var j = 0; j < propertyNameArray.length; j++ ){
  if( propertyNameArray[j].includes( 'answer' ) ){
    if( rawInput.includes( answerDocumentArray[i].propertyNameArray[j] ) ){
      app.tell( answerDocumentArray[i].propertyNameArray[j] );
    }
    else{
      var inputPrompt = app.buildInputPrompt( false, 'Ich habe die leider nicht verstanden!', ['Kannst du deine Antwort wiederholen?'] );
      app.ask( inputPrompt );
    }
  }
}

Google上的操作不像这样工作。每次调用Intent时,您只能向用户发送单个响应。该响应必须在单个 ask() 单个 tell()中。您不能多次打电话给他们。如果您尝试多次调用它,结果是不确定的,但充其量只能得到第一个结果。 (在最坏的情况下,它将崩溃。)

Actions on Google doesn't work like this, however. You can only send a single response to the user for each time your Intent is called. That response must be in a single ask() or a single tell(). You can't call them multiple times. If you try calling it multiple times, the results are undefined, but at best, you'll only get the first result. (At worst, it will crash.)

如果您需要返回多个结果,则需要在循环过程中收集它们,然后仅根据您收集到的结果。

If you need to return multiple results, you need to collect them as you go through the loop and then only say something based on the result of what you've collected.

这篇关于Javascript Firebase Firestore函数未执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆