Firebase 访问实时数据库时Google云函数返回204状态
我有一个通过firebase托管的用于测试目的的网站,它将客户信息存储在实时数据库中,以后需要访问该数据库。当我通过一个html文档和一个访问我的reatime数据库的脚本来实现这一点时,我能够成功地找到信息,但当我将相同的逻辑复制并粘贴到云函数中时,它就不起作用了。我已经尝试了我能想到的一切,现在当我运行这个函数时,它会执行两次(我不知道为什么)。第一次执行以http 204状态结束(未找到任何内容)。第二次执行返回http 500内部服务错误。当我检查firebase上的日志时,它说错误是因为“accounts.getValue()不是函数”。我认为在第一次执行时,函数无法定位帐户,并且在没有尝试查找帐户的情况下再次执行,这可能是它无法运行accounts.getValue()的原因 我想我的主要问题是为什么我的功能无法定位帐户 geturl是我遇到问题的函数 我的实时数据库的结构是 数据库名称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上的日志时,它说错误是因
-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;下面介绍如何为您的移动应用程序构建和部署可调用函数
函数不能按预期工作有多种原因
var Firebase=require(“Firebase”);
)。您不应该使用甚至不需要客户端版本。只需使用Firebase Admin()访问任何数据。如果您在从Admin SDK访问DB时需要某些用户权限,这是一个很好的示例(向下滚动到“您仍然可以执行用户授权的更改…”)帐户
是一个参考
,而不是数据快照
承诺。这可能是以后函数执行不一致的原因
承诺
不会返回承诺
,而一次
会返回。它返回一个用于分离侦听器的函数
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
});