Google云端功能在访问实时数据库时返回204状态

时间:2018-08-10 16:46:25

标签: firebase firebase-realtime-database google-cloud-functions

我有一个通过Firebase托管的用于测试目的的网站,它将客户端信息存储在实时数据库中,以后需要访问。当我通过带有访问我的实时数据库的脚本的单个html文档来执行此操作时,我能够成功找到信息,但是当我将相同的逻辑复制并粘贴到云函数中时,它将无法工作。我已经尝试了所有可以想到的方法,现在当我运行该函数时,它将执行两次(我不确定为什么)。第一次执行以http 204状态结束(找不到内容)。第二次执行返回http 500内部服务错误。当我检查firebase上的日志时,它说该错误是因为“ accounts.getValue()不是函数”。我认为发生的是第一次执行该功能无法找到帐户,并且在没有尝试找到帐户的情况下再次执行,这可能就是为什么它无法运行account.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; 
    });

1 个答案:

答案 0 :(得分:1)

TLDR;遵循此tutorial的步骤,了解如何为您的移动应用构建和部署可调用函数。

有许多原因导致您的功能无法按预期工作。

  1. 您将包括Firebase的客户端版本(var firebase = require("firebase");)。您不应该使用甚至不需要客户端版本。相反,只需使用Firebase Admin(docs)即可访问任何数据。如果从Admin SDK访问数据库时需要某些用户权限,则here是实现此目的的一个很好的示例(向下滚动至“您仍可以执行用户授权的更改...”。)。
  2. 您混合使用了不同的Admin SDK参考。 getValue()是Java Admin SDK的一部分。您应该使用JavaScript等效的val()。另外,在您的代码中,accountsReference而不是DataSnapshot
  3. 您不会退回Promise。这可能是稍后SO Question执行函数时出现不一致的原因。
  4. 您不会从初始函数返回任何内容。如果您不返回任何内容,则不会返回任何内容。该解决方案与3的解决方案相同:返回您的Promise
  5. 您不应在Firebase Functions中使用on。您应该使用once。区别在于on不会返回Promise,而once会返回。它返回一个用于分离侦听器的函数。

我知道这是很多要点,并指出了您的代码中的问题,但是我只是不想给出一个简短的答案,导致您提出另一个问题并等待大约2个小时(在撰写本文时) )作为答案。

我希望这会有所帮助!

代码

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
});