问题
I'm want to use Firebase callbacks to retrieve data from my realtime database, store it in an array, then use that data for data visualization purposes. But when I log the console for the array, it returns empty. I referenced this post in an attempt to understand/fix my error, but I'm still having a lot of trouble.
var genderData=[];
// Get counter values.
function getData(){
var ref = firebase.database().ref().child('counters');
return ref.once('value').then((snapshot) => {
snapshot.forEach((element) => {
genderData.push(element.val()['Male']);
});
return genderData;
});
}
console.log(genderData);
My console shows:
Eventually, I want to be able to use my array to produce a chart with the Chart.js library:
// Bar graph displaying the total number of students by gender.
var ctx = document.getElementById("myChart4").getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Male", "Female", "Non-Binary", "Other", "Unspecified"],
datasets: [{
data: genderData,
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)',
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
title: {
display: true,
text: 'Total Students by Gender'
},
legend:{
display: false
},
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
I've been working on this problem for hours, with no solution. All I want is to create a simple array with my database data, but I've had so much trouble. I really hope someone can help me find an elegant solution.
EDIT:
A bit of my database structure, just in case:
回答1:
Firebase loads data asynchronously. This means that any code that needs access to the data, must be inside the then() callback, or must use a then() callback of its own.
With your current definition of getData, you can call it and use the data with:
getData().then((data) => {
console.log("In callback");
console.log(data);
console.log(genderData);
})
console.log("Outside callback");
console.log(genderData);
If you run this code, you'll see:
Outside callback
[]
Inside callback
[ item1, item2, ... ]
[ item1, item2, ... ]
The things to note here:
- the
Outside callbackcode runs before theInside callbackcode, which is probably not what you expected. - the code outside of the callback runs, the array is still empty. Only once the code inside the callback has run, does the array contain data.
- inside the callback, the
genderDataand thedataare the same. This is because youreturn genderDatain the callback, which is then bubbled up to thethen()method.
The final solution for you is that the code that creates the chart (which is where you need the data), should be inside one of the then callbacks so that it gets called once the data has loaded. For example:
getData().then((data) => {
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Male", "Female", "Non-Binary", "Other", "Unspecified"],
datasets: [{
data: data,
...
来源:https://stackoverflow.com/questions/53450535/firebase-retrieving-and-storing-data-in-array-with-callbacks