为什么在使用管理员时 firebase return 为空
Why does firebase return null when using admin
我正在使用带有 bubble 的 firebase admin sdk 作为 nodejs 项目
这是我正在尝试的代码。这是行不通的。我在底部包含了更新的代码,但现在将保留它,希望其他人可以从我的错误中吸取教训。
function(properties, context) {
console.log('trying')
var list = []
var util = require("util")
var admin = require('firebase-admin');
var serviceAccount = <COPIED/PASTED FROM FIREBASE>
// Fetch the service account key JSON file contenT
if (admin != null) {
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://login-database-brc.firebaseio.com"
})
list.push('logged into app')
var db = admin.database();
var ref = db.ref('BRC/4jV39aEK6jOecLdKONJMKatsEYn1/data')
ref.once('value').then((snapshot) => {
snapshot.val().forEach(element => {
list.push('check')
list.push(element.Name)
})
});
} else {
list.push('nothing happened')
}
// As an admin, the app has access to read and write all data, regardless of Security Rules
return {
data: list
}
}
规则如下
{
"rules":{
"BRC": {
"$uid":{
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
我最终只在输出列表中看到 'logged in'。我希望看到数据桶中每个对象的名称 属性。
我能够使用标准 sdk 并使用密码身份验证在客户端使这项工作正常进行。我似乎无法超越初始化应用程序 Firebase 实例。
我确实有 /BRC 规则需要身份验证,但使用服务器 SDK 我认为这无关紧要
我想访问 BRC/4jV39aEK6jOecLdKONJMKatsEYn1/data
中保存的所有对象
[更新代码以执行同步操作]
function(properties, context) {
var serviceAccount = {'jsonObjectFromFirebase'};
var list =[];
var admin = require("firebase-admin");
// Initialize the app with a service account, granting admin privileges
if (!admin.apps.length){
initializeApp(serviceAccount)
};
// As an admin, the app has access to read and write all data, regardless of Security Rules
admin.database().ref('test').once('value')
.then((snapshot) => {
snapshot.val().forEach(element => {
let a = element.name;
list.push(a);
})
return_data(list)
});
function return_data (list){
return { data: list};
};
function initializeApp (serviceAccount){
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://thunkableproject-f51d9-default-rtdb.firebaseio.com"
});
}
}
问题是现在从未调用 return_data。所以我不确定这里发生了什么。
[更新 2,再次尝试创建同步调用
var list =[]
var admin = require("firebase-admin");
// Initialize the app with a service account, granting admin privileges
if (!admin.apps.length){
initializeApp(serviceAccount)
}
// As an admin, the app has access to read and write all data, regardless of Security Rules
admin.database().ref('BRC/4jV39aEK6jOecLdKONJMKatsEYn1/data').once("value", function(snapshot){
let element = snapshot.val()
let list = []
for (var key in element) {
list.push(element[key].Name)
}
return_data(list)
})
function return_data (list){
return { data: list}
}
function initializeApp (serviceAccount){
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://login-database-brc.firebaseio.com"
});
}
这个我也试过了,没用
var promise = admin.database().ref('BRC/4jV39aEK6jOecLdKONJMKatsEYn1/data').once("value");
promise.then(snapshot => {
let element = snapshot.val()
let list = []
for (var key in element) {
list.push(element[key].name)
};})
.catch(error => {
alert(error)
});
return { data: list}
更新 9:23 美国东部时间 12/29/20
我想我现在正在以异步方式调用此函数,应该等待回调。现在的问题是 .then() 中的代码永远不会执行。
function getData() {
var promise = admin.database().ref('BRC/4jV39aEK6jOecLdKONJMKatsEYn1/data').once("value");
promise.then(snapshot => {
let element = snapshot.val()
let list = []
for (var key in element) {
list.push(element[key].Name)
};
return list;
})
.catch(error => {
return error
});
return promise;
}
getData().then((list) => {
return { "data": list }
})
问题是您的 return { data: list }
在 list.push(element.Name)
发生之前运行。这是因为数据是从 Firebase 异步加载的,并且超出了您预期的顺序。此行为在客户端和服务器端 SDK 上都是相同的,并且在现在大多数基于云的 API 中都是如此。
典型的解决方案是 return 承诺,而不是实际值。与其在这里解释,我建议阅读这些:
- 关于 Promises 的 MDN 文档
- Doug Stevenson 的优秀video series and blog post
- Why Does Firebase Lose Reference outside the once() Function?
编辑:
在您的编辑中,您必须return 承诺。例如在这样定义的函数中:
function getData() {
var promise = admin.database().ref('BRC/4jV39aEK6jOecLdKONJMKatsEYn1/data').once("value");
promise.then(snapshot => {
let element = snapshot.val()
let list = []
for (var key in element) {
list.push(element[key].name)
};
return list;
})
.catch(error => {
alert(error)
});
return promise;
}
现在您可以像这样使用此功能:
readData().then((list) => {
console.log(data);
})
请注意(如评论中所述)这 不会 使代码同步,因为这是不可能的。它只是 return 对调用者的承诺,然后调用者 then
“等待”数据可用。
如果您使用的是足够现代的平台,您可以在最后一个片段中使用 await
:
var list = await readData();
console.log(data);
虽然这看起来更熟悉,但它在幕后仍然做着完全相同的事情,并且不是同步的。
在一位朋友的帮助下,我得到了你的反馈 Frank van Puffelen。
function(properties, context) {
var serviceAccount = <serviceAccountPath>
var admin = require("firebase-admin");
// Initialize the app with a service account, granting admin privileges
if (!admin.apps.length) {
initializeApp(serviceAccount)
}
function initializeApp(serviceAccount) {
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://login-database-brc.firebaseio.com"
});
}
let list = context.async(async callback => {
try {
const snapshot = await admin.database().ref('BRC/4jV39aEK6jOecLdKONJMKatsEYn1/data').once("value");
const element = snapshot.val()
let list = []
for (key in element) {
list.push(element[key].Name)
};
callback(null, list);
} catch (err) {
callback(err);
}
})
return {
"data": list
}
}
我正在使用带有 bubble 的 firebase admin sdk 作为 nodejs 项目
这是我正在尝试的代码。这是行不通的。我在底部包含了更新的代码,但现在将保留它,希望其他人可以从我的错误中吸取教训。
function(properties, context) {
console.log('trying')
var list = []
var util = require("util")
var admin = require('firebase-admin');
var serviceAccount = <COPIED/PASTED FROM FIREBASE>
// Fetch the service account key JSON file contenT
if (admin != null) {
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://login-database-brc.firebaseio.com"
})
list.push('logged into app')
var db = admin.database();
var ref = db.ref('BRC/4jV39aEK6jOecLdKONJMKatsEYn1/data')
ref.once('value').then((snapshot) => {
snapshot.val().forEach(element => {
list.push('check')
list.push(element.Name)
})
});
} else {
list.push('nothing happened')
}
// As an admin, the app has access to read and write all data, regardless of Security Rules
return {
data: list
}
}
规则如下
{
"rules":{
"BRC": {
"$uid":{
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
我最终只在输出列表中看到 'logged in'。我希望看到数据桶中每个对象的名称 属性。
我能够使用标准 sdk 并使用密码身份验证在客户端使这项工作正常进行。我似乎无法超越初始化应用程序 Firebase 实例。
我确实有 /BRC 规则需要身份验证,但使用服务器 SDK 我认为这无关紧要
我想访问 BRC/4jV39aEK6jOecLdKONJMKatsEYn1/data
中保存的所有对象[更新代码以执行同步操作]
function(properties, context) {
var serviceAccount = {'jsonObjectFromFirebase'};
var list =[];
var admin = require("firebase-admin");
// Initialize the app with a service account, granting admin privileges
if (!admin.apps.length){
initializeApp(serviceAccount)
};
// As an admin, the app has access to read and write all data, regardless of Security Rules
admin.database().ref('test').once('value')
.then((snapshot) => {
snapshot.val().forEach(element => {
let a = element.name;
list.push(a);
})
return_data(list)
});
function return_data (list){
return { data: list};
};
function initializeApp (serviceAccount){
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://thunkableproject-f51d9-default-rtdb.firebaseio.com"
});
}
}
问题是现在从未调用 return_data。所以我不确定这里发生了什么。
[更新 2,再次尝试创建同步调用
var list =[]
var admin = require("firebase-admin");
// Initialize the app with a service account, granting admin privileges
if (!admin.apps.length){
initializeApp(serviceAccount)
}
// As an admin, the app has access to read and write all data, regardless of Security Rules
admin.database().ref('BRC/4jV39aEK6jOecLdKONJMKatsEYn1/data').once("value", function(snapshot){
let element = snapshot.val()
let list = []
for (var key in element) {
list.push(element[key].Name)
}
return_data(list)
})
function return_data (list){
return { data: list}
}
function initializeApp (serviceAccount){
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://login-database-brc.firebaseio.com"
});
}
这个我也试过了,没用
var promise = admin.database().ref('BRC/4jV39aEK6jOecLdKONJMKatsEYn1/data').once("value");
promise.then(snapshot => {
let element = snapshot.val()
let list = []
for (var key in element) {
list.push(element[key].name)
};})
.catch(error => {
alert(error)
});
return { data: list}
更新 9:23 美国东部时间 12/29/20
我想我现在正在以异步方式调用此函数,应该等待回调。现在的问题是 .then() 中的代码永远不会执行。
function getData() {
var promise = admin.database().ref('BRC/4jV39aEK6jOecLdKONJMKatsEYn1/data').once("value");
promise.then(snapshot => {
let element = snapshot.val()
let list = []
for (var key in element) {
list.push(element[key].Name)
};
return list;
})
.catch(error => {
return error
});
return promise;
}
getData().then((list) => {
return { "data": list }
})
问题是您的 return { data: list }
在 list.push(element.Name)
发生之前运行。这是因为数据是从 Firebase 异步加载的,并且超出了您预期的顺序。此行为在客户端和服务器端 SDK 上都是相同的,并且在现在大多数基于云的 API 中都是如此。
典型的解决方案是 return 承诺,而不是实际值。与其在这里解释,我建议阅读这些:
- 关于 Promises 的 MDN 文档
- Doug Stevenson 的优秀video series and blog post
- Why Does Firebase Lose Reference outside the once() Function?
编辑:
在您的编辑中,您必须return 承诺。例如在这样定义的函数中:
function getData() {
var promise = admin.database().ref('BRC/4jV39aEK6jOecLdKONJMKatsEYn1/data').once("value");
promise.then(snapshot => {
let element = snapshot.val()
let list = []
for (var key in element) {
list.push(element[key].name)
};
return list;
})
.catch(error => {
alert(error)
});
return promise;
}
现在您可以像这样使用此功能:
readData().then((list) => {
console.log(data);
})
请注意(如评论中所述)这 不会 使代码同步,因为这是不可能的。它只是 return 对调用者的承诺,然后调用者 then
“等待”数据可用。
如果您使用的是足够现代的平台,您可以在最后一个片段中使用 await
:
var list = await readData();
console.log(data);
虽然这看起来更熟悉,但它在幕后仍然做着完全相同的事情,并且不是同步的。
在一位朋友的帮助下,我得到了你的反馈 Frank van Puffelen。
function(properties, context) {
var serviceAccount = <serviceAccountPath>
var admin = require("firebase-admin");
// Initialize the app with a service account, granting admin privileges
if (!admin.apps.length) {
initializeApp(serviceAccount)
}
function initializeApp(serviceAccount) {
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://login-database-brc.firebaseio.com"
});
}
let list = context.async(async callback => {
try {
const snapshot = await admin.database().ref('BRC/4jV39aEK6jOecLdKONJMKatsEYn1/data').once("value");
const element = snapshot.val()
let list = []
for (key in element) {
list.push(element[key].Name)
};
callback(null, list);
} catch (err) {
callback(err);
}
})
return {
"data": list
}
}