在HttpsCallableResult完成之前等待所有回调返回

时间:2019-01-17 11:57:56

标签: node.js firebase unity3d google-cloud-functions

我在Unity中使用Firebase Functions。在数据库函数完成之前,main函数将返回。我仍然对Node.js还是陌生的,并且我仍在设法了解所有异步回调的内容。

我尝试了CallAsync,ContinueWith和Coroutines,但是该函数始终在第一次返回后继续(我使用Task.isCompleted()进行检查)。

我的Node.js函数是这样的:

exports.my_fn = functions.https.onCall((data, context) => {
    dbsessions.child(id).once("value").then(function(snapshot) {
      if (snapshot.val()) {
        Create();
      } else {
        Move(session);
      }});
  });

function Move(session) {
  if (session["error"]) {
    return return_stuff;
  } else {
      if (some_condition) {
        dbsessions.child(id).set(sson, function(set_error) {
          if (set_error) {
            return return_stuff;
          } else {
            return return_stuff;
          }
      });
      } else {
      dbaimoves.child(stt).child(dif).once("value").then(function(snapshot) {
        if (snapshot.val()) {
          return return_stuff;
        } else {
          if (!first) {
            dbsessions.child(id).set(sson, function(set_error) {
                if (set_error) {
                  return return_stuff;
                } else {
                  return return_stuff;
                }
            });
        } else {
          return return_stuff;
        }
      }
      }, function(errorObject) {
        if (errorObject) {
          return return_stuff;
        }
      });
}}}

var Create = function(data, callback) {
    dbdifficulty.child(data).once("value").then(function(snapshot) {
      if (snapshot.val()) {
        return callback();
      } else {
        dbsessions.child(data.id).set(data, function(set_error) {
          if (set_error) {
            return callback();
          } else {
            return callback();
          }});
    }});
}

(为了简化问题,我跳过了不必要的数据)。它基本上是嵌套的返回,数据库操作,回调和函数相互调用。

我的C#Unity代码是这样的:

private async Task<string> AddMessageAsync(string text)
    {
        // Create the arguments of the callable function.
        var data = new Dictionary<string, string>();
        data["s"] = text;
        data["d"] = "0";

        var function = func.GetHttpsCallable("my_fn");
        var Tfn = function.CallAsync(data);
        var TRes = await Tfn;

        if (Tfn.IsCompleted)
        {
            JFunc result = JsonUtility.FromJson<JFunc>(TRes.Data.ToString());
            Debug.Log("error:" + result.error);
            return result.move;
        }
        return "error";
    }

上面的代码类似于我的实际代码,该代码从Unity调用该函数,该函数在Firebase上运行并很快返回(在进入Create()或Move()之前),Unity接收结果(空)。几秒钟后,该功能在Firebase上成功完成,但是Unity没有收到任何有关此信息的信息(或者也许收到了,但是我无法正确处理)。

我需要知道:

  1. 如何使主函数返回其他函数返回的内容,以及

  2. 如何让C#等待并继续监听返回的值,而不是认为第一次返回后任务已完成。如果我只能在结果准备好后才能返回,那会更好。

1 个答案:

答案 0 :(得分:0)

要使Cloud Functions代码返回一个值,请确保每个函数都返回一个值或一个P​​romise。承诺“冒泡”意味着只要您在每个级别上都有一个return,从最嵌套的代码返回的值将返回到顶级。

因此,在快速扫描的代码中,您需要:

exports.my_fn = functions.https.onCall((data, context) => {
    return dbsessions.child(id).once("value").then(function(snapshot) {
      if (snapshot.val()) {
        return Create();
      } else {
        return Move(session);
      }});
  });

var Create = function(data, callback) {
    return dbdifficulty.child(data).once("value").then(function(snapshot) {
      if (snapshot.val()) {
        return callback();
      } else {
        return dbsessions.child(data.id).set(data, function(set_error) {
          if (set_error) {
            return callback();
          } else {
            return callback();
          }});
    }});
}

我仅在此处检测了顶级my_fnCreate,以显示操作方法。您必须自己为Move做同样的事情。