Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Firebase 访问实时数据库时Google云函数返回204状态_Firebase_Firebase Realtime Database_Google Cloud Functions - Fatal编程技术网

Firebase 访问实时数据库时Google云函数返回204状态

Firebase 访问实时数据库时Google云函数返回204状态,firebase,firebase-realtime-database,google-cloud-functions,Firebase,Firebase Realtime Database,Google Cloud Functions,我有一个通过firebase托管的用于测试目的的网站,它将客户信息存储在实时数据库中,以后需要访问该数据库。当我通过一个html文档和一个访问我的reatime数据库的脚本来实现这一点时,我能够成功地找到信息,但当我将相同的逻辑复制并粘贴到云函数中时,它就不起作用了。我已经尝试了我能想到的一切,现在当我运行这个函数时,它会执行两次(我不知道为什么)。第一次执行以http 204状态结束(未找到任何内容)。第二次执行返回http 500内部服务错误。当我检查firebase上的日志时,它说错误是因

我有一个通过firebase托管的用于测试目的的网站,它将客户信息存储在实时数据库中,以后需要访问该数据库。当我通过一个html文档和一个访问我的reatime数据库的脚本来实现这一点时,我能够成功地找到信息,但当我将相同的逻辑复制并粘贴到云函数中时,它就不起作用了。我已经尝试了我能想到的一切,现在当我运行这个函数时,它会执行两次(我不知道为什么)。第一次执行以http 204状态结束(未找到任何内容)。第二次执行返回http 500内部服务错误。当我检查firebase上的日志时,它说错误是因为“accounts.getValue()不是函数”。我认为在第一次执行时,函数无法定位帐户,并且在没有尝试查找帐户的情况下再次执行,这可能是它无法运行accounts.getValue()的原因

我想我的主要问题是为什么我的功能无法定位帐户

geturl是我遇到问题的函数

我的实时数据库的结构是 数据库名称

-accounts

  -some data

  -more data

  -more account data
-ActiveQRs
  -some data...
我的云函数index.js文件是

const functions = require('firebase-functions');
const express = require('express');

const cors = require('cors')({origin: true});

var firebase = require("firebase");


var admin = require("firebase-admin");

require("firebase/auth");
require("firebase/database");
//require("firebase/firestore");
//require("firebase/messaging");
require("firebase/functions");


var serviceAccount = require("./serviceKey.json");


// Initialize the app with a service account, granting admin 
//privileges
admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "https://databaseName.firebaseio.com"
});

const displayqr = express();
const geturl = express();


displayqr.get('/displayqr', (request, response) => {
    console.log("response sent");
        response.send("testio/qrdisplay.html");
    });




 exports.displayqr = functions.https.onRequest(displayqr);



 exports.geturl = functions.https.onCall((email) => {

    const mail = email.toString();
    var result = "";
    result = result + mail;
       var accounts = 
admin.database().ref("livsuiteform/accounts");
       result = (accounts.getValue());
       accounts.orderByKey().on("value", function(snapshot) {
          snapshot.forEach(function(data) {
            if (data.child("Email").val() == mail) {
              var firstName = data.child("FirstName").val();
              var lastName = data.child("LastName").val();
              result = firstname;
              result = "if loop entered";
              } // end if
         //     return "name not found";
              }); // end for each
          }); // end order by
       return result; 
    });
TLDR;下面介绍如何为您的移动应用程序构建和部署可调用函数

函数不能按预期工作有多种原因

  • 您正在包括Firebase的客户端版本(
    var Firebase=require(“Firebase”);
    )。您不应该使用甚至不需要客户端版本。只需使用Firebase Admin()访问任何数据。如果您在从Admin SDK访问DB时需要某些用户权限,这是一个很好的示例(向下滚动到“您仍然可以执行用户授权的更改…”)
  • 您混合了不同的管理SDK引用。是用于Java的管理SDK的一部分。您应该使用与JavaScript等效的代码。另外,在代码中,
    帐户
    是一个
    参考
    ,而不是
    数据快照
  • 您没有返回您的
    承诺。这可能是以后函数执行不一致的原因
  • 您没有从初始函数返回任何内容。如果你不返回任何内容,那么你的应用程序将不会返回任何内容。解决方案与3的解决方案相同:返回您的
    承诺
  • 您不应该在Firebase函数中使用。你应该使用。区别在于上的
    不会返回
    承诺
    ,而
    一次
    会返回。它返回一个用于分离侦听器的函数
  • 我知道这是很多要点并指出了代码中的问题,但我只是不想给出一个肤浅的答案,这会导致您提出另一个问题并等待2个小时(在撰写本文时)才能得到答案

    我希望这有帮助

    代码
    PS我希望此函数在从外部网站调用时读取数据库日期,而不是在数据库写入或任何其他类型的事件中。您是否在控制台中从firebase获取快照数据?在网站控制台上,由于此函数正在服务器上运行,因此未显示任何内容,但是在firebase日志中,我没有看到任何消息日志,我在任何地方都看不到console.log,这就是为什么我的结果是一个字符串,最终我希望它返回一个url,但我一直在返回结果并将其用作调试控制台,不,当我执行result=snapshot.getValue()时,我无法看到快照数据;感谢Bryan,这很有帮助,我想我仍然很难做出承诺,哪些代码行需要承诺,我如何才能回报承诺?我将on替换为once,但我的函数仍然执行两次,并且在运行时需要大约2秒钟,而这应该是非常困难的quick@DHolthaus我添加了一些代码,可以让它正确运行
    geturl
    的外观应该与上面的类似。我建议浏览一下我链接的教程。我想它现在看起来几乎和我的代码一模一样,但它仍然无法从数据库中检索信息,我不确定为什么。现在,当我调用函数时(现在我让我的应用程序将函数的结果记录到控制台),它返回所使用的电子邮件,意思是result=result+mail;有效,但其他声明没有。在firebase日志中,现在我的函数在每次调用中运行三次,第三次调用返回一个错误,表示未定义firstname。我浏览了教程,但主要是在客户端,我对promises没有太多了解,您能告诉我您更改了什么吗?我所能看到的唯一变化是改为一次并使用。then@DHolthaus我变了不少。我通过返回accounts.orderByKey()…
    返回了一个
    Promise
    。我修复了
    firstname
    firstname
    不同的问题。我删除了函数
    返回结果末尾的返回。如果您复制/粘贴我提供的代码,您应该看到结果将是
    电子邮件
    名字
    exports.geturl = functions.https.onCall((email) => {
    
      const mail = email.toString();
      var result = "";
      result = result + mail;
      var accounts = admin.database().ref("livsuiteform/accounts");
      return accounts.orderByKey().once("value")
        .then(function (snapshot) {
          snapshot.forEach(function (data) {
            if (data.child("Email").val() == mail) {
              var firstName = data.child("FirstName").val();
              var lastName = data.child("LastName").val();
              result = firstName;
              result = "if loop entered";
            } // end if
            //     return "name not found";
          }); // end for each
          return result;
        }); // end order by
    });