简体   繁体   English

从一个 firestore 文档中检索数据以查询另一个

[英]Retrieving data from one firestore document to query another

I have 2 documents in a Firestore collection.我在 Firestore 集合中有 2 个文档。

I want to query one document to get the number plate of a user, and with that number plate I want to retrieve the vehicle's data which is stored in the other document.我想查询一个文档以获取用户的车牌号,并使用该车牌号检索存储在另一个文档中的车辆数据。

This is my code:这是我的代码:

function get_full_name_by_nplate(nplate){
    var docRef = global_db.collection("customer_data").doc('web-app-vehicle-data');
    docRef.get().then(function(doc) {
        var data = doc.data();
        given_name = data["vehicles"][nplate]["policy_holder_given_name"];
        family_name = data["vehicles"][nplate]["policy_holder_family_name"];
    
        console.log("given name: " + given_name); //this prints correctly! ==> "Jaime"
    
        return given_name + " " + family_name;//this returns undefined
    });
}

//load user data ////driving scores from backend
function loadUserData(user){
    var nplate_list;

    var docRef = global_db.collection("customer_data").doc('web-app-user-data');
    docRef.get().then(function(doc) {
        var data = doc.data();
        user_data = data["users"][user.email];
        nplate_list = user_data["number_plates"];
    
    }).then(function(){

        for(nplate of nplate_list){
        
            get_full_name_by_nplate(nplate).then(full_name => {
                console.log(full_name);//this prints undefined
            });
        }
    });
}

I have read this answer How to return value from firestore database?我读过这个答案如何从 firestore 数据库返回值? and I understand that Firestore returns promises so I always have to use .then after a Firestore data retrieval.我知道 Firestore 会返回承诺,所以我总是必须在 Firestore 数据检索后使用.then

Although I am able to print the correct given_name to the console, the function function get_full_name_by_nplate returns undefined虽然我能够将正确的given_name打印到控制台,但 function function get_full_name_by_nplate返回undefined

What perhaps isn't working is that I am nesting one promise inside another, but I don't know if it is wrong to nest them, nor how to do it without nesting.可能不起作用的是我将一个 promise 嵌套在另一个中,但我不知道嵌套它们是否错误,也不知道如何在不嵌套的情况下进行嵌套。

UPDATE更新

With the answer from @kvetis I have improved the code and now it works.通过 @kvetis 的回答,我改进了代码,现在它可以工作了。 However it still feels wrong, I had to pass nplate_list as a parameter from one .then() to the next one.. I wouldn't want to imagine if I had to pass it on 5 times, and additionally I am still nesting 2 .then() statements which also feels unnatural.然而,它仍然感觉不对,我不得不将nplate_list作为参数从一个 .then .then()传递到下一个。我不想想象如果我必须将它传递 5 次,而且我还在嵌套 2 .then()语句也感觉不自然。

//load user data ////driving scores from backend
function loadUserData(user){



var docRef = global_db.collection("customer_data").doc('web-app-user-data');
    docRef.get().then(function(doc) {
        var data = doc.data();

        global_user_data = data["users"][user.email];
        //console.log(global_user_data["number_plates"]);

        var user_name  = global_user_data["name"] + " " + global_user_data["surname"];
        document.getElementById("welcome_div").innerHTML = user_name;

        var nplate_list = global_user_data["number_plates"];
        
        console.log("these are the nplates: " + nplate_list);
        
        return nplate_list;
    })
    
    .then(function (nplate_list) {
        var docRef = global_db
            .collection("customer_data")
            .doc("web-app-vehicle-data");
        
        docRef.get().then(function(doc) {
            global_vehicle_data = doc.data()["vehicles"];
            
            var cust_dropdown = document.getElementById("cust-search-dropdown");
            dropdown_content = "";
            
            for(nplate of nplate_list){
                //console.log(nplate);
                var full_name = get_full_name_by_nplate(global_vehicle_data, nplate);
                dropdown_content += "<div class=\"cust-dropdown-items\"><a href=\"#\" id=\"" + nplate + "\" class=\"number-plate-links\">" + nplate + " " + full_name + "</a></div>";
            }
            
            cust_dropdown.innerHTML = dropdown_content;
            addListeners();
            
            // If user has only 1 vehicle then pre-load it
            if(nplate_list.length == 1){
                select_customer_express(nplate_list[0]);
            }
        });
    });
}

The problem is that you're probably reading dropdown_content before all the promises complete.问题是您可能在所有承诺完成之前阅读dropdown_content You have to wait until all of get_full_name_by_nplate complete.您必须等到所有get_full_name_by_nplate完成。

Unfortunately your code is written so, that you download the vehicle data over and over again.不幸的是,你的代码是这样写的,你一遍又一遍地下载车辆数据。

What would be the best is to chain the two document loads one after other.最好的办法是将两个文档加载一个接一个地链接起来。 Otherwise it will be slow and rather costly, since you're getting billed per document get.否则它会很慢而且成本很高,因为您要按获取的文档收费。

function get_full_name_by_nplate(data, nplate) {

    given_name = data["vehicles"][nplate]["policy_holder_given_name"];
    family_name = data["vehicles"][nplate]["policy_holder_family_name"];

    return given_name + " " + family_name;
  
}

//load user data ////driving scores from backend
function loadUserData(user) {
  var nplate_list;

  var docRef = global_db.collection("customer_data").doc("web-app-user-data");
  docRef
    .get()
    .then(function (doc) {
      var data = doc.data();
      user_data = data["users"][user.email];
      nplate_list = user_data["number_plates"];
    })

    .then(function () {
      var docRef = global_db
        .collection("customer_data")
        .doc("web-app-vehicle-data");
      return docRef.get();
    })

    .then(function (doc)  { return doc.data()})

    .then(function (vehicle_data) {
      for (nplate of nplate_list) {
       var full_name=  get_full_name_by_nplate(vehicle_data,nplate);
          dropdown_content +=
            '<div class="cust-dropdown-items"><a href="#" id="' +
            nplate +
            '" class="number-plate-links">' +
            nplate +
            " " +
            full_name +
            "</a></div>";
        
      }
      // now you do things with `dropdown_content`
    });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM