【问题标题】:Why does firebase return null when using admin为什么使用管理员时firebase返回null
【发布时间】:2020-12-31 00:26:08
【问题描述】:

我正在使用带有 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"
        }
    }
}
}

我最终只在输出列表中看到“登录”。我希望看到数据桶中每个对象的 name 属性。

我能够使用标准 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}

2020 年 12 月 29 日美国东部标准时间 9:23 更新

我想我现在正在以异步方式调用这个函数,应该等待回调。现在的问题是 .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 }
})

【问题讨论】:

    标签: node.js firebase firebase-realtime-database firebase-admin


    【解决方案1】:

    问题是您的return { data: list }list.push(element.Name) 发生之前运行。这是因为数据是从 Firebase 异步加载的,并且超出了您预期的顺序。这种行为在客户端和服务器端 SDK 上都是相同的,而且在现在大多数基于云的 API 中都可以找到。

    典型的解决方案是返回一个承诺,而不是实际值。我建议阅读以下内容,而不是在这里解释:


    编辑

    在您的编辑中,您必须返回承诺。例如在这样定义的函数中:

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

    请注意(如 cmets 中所述)这确实不会使代码同步,因为这是不可能的。它只是将承诺返回给调用者,然后调用者使用then“等待”数据可用。

    如果您使用的是足够现代的平台,则可以在最后一个 sn-p 中使用await

    var list = await readData();
    console.log(data);
    

    虽然这看起来更熟悉,但它仍然在幕后做完全相同的事情,并且不是同步的。

    【讨论】:

    • 我已尝试解决。请参阅上面的代码更新。也许您可以进一步指出正确的方向。我是 firebase 和 JS 的婴儿
    • 您不能使异步操作同步。您无法退回尚未加载的内容。我的答案中的最后一个链接提供了多个如何处理此问题的示例,我在您的编辑中没有看到任何内容。
    • 感谢您抽出宝贵时间@Frank van Puffelen。我试图重新创建同步调用。仍然不明白如何返回承诺并等待它。我按照您上一个答案中最后一个链接的示例进行操作。并包含上面的代码
    • 再次:您不能使异步操作同步。您无法退回尚未加载的内容。但是通过使用承诺,您可以允许调用者“等待”直到数据可用。我在回答中包含了一个例子。但在这一点上,我只是重复我链接的答案中的内容。因此,如果您仍在为此苦苦挣扎,我建议您阅读这些链接以及其中的一些 许多 其他教程。处理异步函数调用最初很棘手,但如果您想使用 Firebase 等云 API,则必须接受它。
    • 好的。所以我相信我现在正确地使用了代码。我试图模仿你上面展示的内容。我声明 getData 并返回一个承诺。奇怪的是我没有得到任何输出。即使我不使用承诺。我已经明确定义了一个变量。我至少希望返回 null 或 0 的数组。在最新更新中使用此代码我没有得到任何输出。再次感谢您的宝贵时间!
    【解决方案2】:

    在朋友的帮助下,我得以听取您的反馈 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
        }
    
    
    }
    

    【讨论】:

      猜你喜欢
      • 2020-04-30
      • 2019-05-21
      • 2012-03-07
      • 2019-01-27
      • 2021-09-27
      • 1970-01-01
      • 2020-08-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多