Javascript execution order when pulling Firebase data

Multi tool use
Multi tool use


Javascript execution order when pulling Firebase data



After I authenticate to Firebase with Google auth, I get this console.log output and the JavaScript seems to bounce around in execution order. Here's my console output and the javascript code.


console.log



Why does "controller is: Pellet_Pirate_1" display at the log end rather than at the beginning where the code executes to pull this value from Firebase? My "GLOBAL CONTROLLER" and other logs of the contr global variable should be valued as well... I am trying to use contr as a global variable and it is defined at the top of my script tag


contr


contr



Any help would be greatly appreciated... I've banged my head on this one for many hours now!



console.log


<script type="text/javascript">
var contr = undefined;
function PelletPirate() {
this.userPic = document.getElementById('user-pic');
this.userName = document.getElementById('user-name');
this.signInButton = document.getElementById('sign-in');
this.signOutButton = document.getElementById('sign-out');
this.signOutButton.addEventListener('click', this.toggleSignOut.bind(this));
this.signInButton.addEventListener('click', this.toggleSignIn.bind(this));
this.initFirebase();
}

// Sets up shortcuts to Firebase features and initiate firebase auth.
PelletPirate.prototype.initFirebase = function() {
//FlymanEdit Shortcuts to Firebase SDK features.
this.auth = firebase.auth();
this.database = firebase.database();
this.storage = firebase.storage();
//FlymanEdit Initiates Firebase auth and listen to auth state changes.
this.auth.onAuthStateChanged(this.onAuthStateChanged.bind(this));
};

PelletPirate.prototype.toggleSignIn = function() {
var provider = new firebase.auth.GoogleAuthProvider(); // [Start createprovider]
provider.addScope('https://www.googleapis.com/auth/plus.login'); // [START addscopes]
this.auth.signInWithPopup(provider).then(function(result)
{
var token = result.credential.accessToken;
var user = result.user;
console.log('token: ' + token);

}).catch(function(error) {
var errorCode = error.code;
var errorMessage = error.message;
var email = error.email;
var credential = error.credential; // The firebase.auth.AuthCredential type that was used.
if (errorCode === 'auth/account-exists-with-different-credential') {
alert('You have already signed up with a different auth provider for that email.');
}
else {
console.error(error);
}
});
}

// Sign-out.
PelletPirate.prototype.toggleSignOut = function() {
this.auth.signOut();
console.log('******************** USER SIGNED OUT *********************');
};

PelletPirate.prototype.onAuthStateChanged = function(user) { // Triggers when user's auth state changes.
if (user) { // User is signed in!
// let's go fetch the Pellet Pirate controller name based on the logged in user!
console.log('user.uid is: ' + user.uid);
firebase.database().ref().child("owners").orderByChild("userId").equalTo(user.uid).on('value', function (snapshot) {
snapshot.forEach(function(childSnapshot) {
contr = childSnapshot.val().controller;
//MYLIBRARY.init([controller, 1, "controller"]);
//MYLIBRARY.passVar();
console.log('controller is: ' + contr);
return contr;
});
});
var currentDate = new Date();
var profilePicUrl = user.photoURL;
var userName = user.displayName;
var displayName = user.displayName;
var email = user.email;
var emailVerified = user.emailVerified;
var photoURL = user.photoURL;
var isAnonymous = user.isAnonymous;
var uid = user.uid;
var refreshToken = user.refreshToken;
var providerData = user.providerData;
//console.log('You have signed in: ' + userName );
console.log('*************** signed in: ' + userName + ' *****************');
console.log('GLOBAL CONTROLLER: ' + contr);

document.getElementById('authed').style.visibility = 'visible';
document.getElementById('authed2').style.visibility = 'visible';
document.getElementById('gauges').style.visibility = 'visible';
document.getElementById('graph').style.visibility = 'visible';
document.getElementById('parameters').style.visibility = 'visible';
document.getElementById('ParmForm').style.visibility = 'visible';
document.getElementById('ClearDataButton').style.visibility = 'visible';
document.getElementById('AddProgramButton').style.visibility = 'visible';
document.getElementById('programrows').style.visibility = 'visible';

// Set the user's profile pic and name.
this.userPic.style.backgroundImage = 'url(' + profilePicUrl + ')';
this.userName.textContent = userName;

// Show user's profile and sign-out button.
this.userName.removeAttribute('hidden');
this.userPic.removeAttribute('hidden');
this.signOutButton.removeAttribute('hidden');

// Hide sign-in button.
this.signInButton.setAttribute('hidden', 'true');



console.log('before firebase controller is: ' + contr);
//controllerName = "Pellet_Pirate_1";

//Firebase
var TempsRef = Ref.child('ControllerData/' + contr + '/Temps');

console.log('after firebase controller is: ' + contr);

TempsRef.limitToLast(3600/3*16).once("value", function(snapshot) { //Limit to last 16 hours
var Ts = snapshot.val();
for (var k in Ts) {
T1.push([Ts[k].time, Ts[k].T1]);
T2.push([Ts[k].time, Ts[k].T2]);
T3.push([Ts[k].time, Ts[k].T3]);
TT.push([Ts[k].time, Ts[k].TT]);
console.log('in snapshot');
}
TempsRef.limitToLast(1).on("child_added", function(snapshot, prevChildKey) { //Establish callback
var Ts = snapshot.val();
T1.push([Ts.time, Ts.T1]);
T2.push([Ts.time, Ts.T2]);
T3.push([Ts.time, Ts.T3]);
TT.push([Ts.time, Ts.TT]);
UpdatePlot();
console.log('in snapshot-previousChildKey' );
//console.log('in snapshot-PCK-controllerName is:' + controllerName);
});
UpdatePlot();
});

TempsRef.on("child_removed", function(snapshot, prevChildKey) {
T1 = ;
T2 = ;
T3 = ;
TT = ;
UpdatePlot();
});
}

else { // User is signed out!
// Hide user's profile and sign-out button.
this.userName.setAttribute('hidden', 'true');
this.userPic.setAttribute('hidden', 'true');
this.signOutButton.setAttribute('hidden', 'true');

document.getElementById('authed').style.visibility = 'hidden';
document.getElementById('authed2').style.visibility = 'hidden';
document.getElementById('gauges').style.visibility = 'hidden';
document.getElementById('graph').style.visibility = 'hidden';
document.getElementById('parameters').style.visibility = 'hidden';
document.getElementById('ParmForm').style.visibility = 'hidden';
document.getElementById('ClearDataButton').style.visibility = 'hidden';
document.getElementById('AddProgramButton').style.visibility = 'hidden';
document.getElementById('programrows').style.visibility = 'hidden';
// Show sign-in button.
this.signInButton.removeAttribute('hidden');

// undefine the controller
contr = undefined;
}
}; // [ END onAuthStateChanged - auth state listener]




1 Answer
1



Because on() is asynchronous. It returns immediately while the query is happening in the background. Meanwhile, the code immediately after that runs until the first time the callback you provided to it is invokes with a snapshot of results.


on()





thank you Doug. Is there a way to make it synchronous? I'm getting exactly what you demo'd in your medium.com article! Would the new JavaScript async/await method work here from your medium.com article?
– D Brian Beardmore
Jul 2 at 2:20






Everything in JavaScript is async. That's a core part of the language. You can't change that, nor should you want to. You can't use async/await for on(), because it doesn't return a promise, and th e listener doesn't finish until you call off(). Maybe you want to use once() instead, if you just want a single value a single time.
– Doug Stevenson
Jul 2 at 2:35





I tried replacing on() with once() but to no avail. it operates the same way. Basically i need this callback to return the users controller name because I need it when the user logs in so I can tell firebase where to write the users data. it's part of my multi-tenant model. Is there a different approach i should try here or any reference post you could point me to that might have an approach that could work? again, thanks for the help!
– D Brian Beardmore
Jul 2 at 3:22






As I said, everything in JavaScript is async (as are all Firebase APIs). You would switch from on() to once() if you need data a single time, and then you can use the promise it returns to continue execution. Use of promises is pretty foundational to JavaScript - learn them.
– Doug Stevenson
Jul 2 at 3:24





thanks Doug. I've reviewed your youtube videos on promises and I'm trying to learn it. I'm an intermediate c++ embedded programmer, learning javascript! Can you point me to a good tutorial or example that executes the promise to get what I'm after? thanks for any help.
– D Brian Beardmore
Jul 3 at 0:14






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

2 eyBHie 96f,GyjSOpIZgn 7 AHdidibT5F4Kqw,R,0JLNMGGmguYOkMXSlk 03JnzIl I,4HDf4qj,2cfiKt Wdzy badBP
A3o IWDx2 sKLdUab,gJ,d,MgEXb,npf,CcenbPsbJGhnwAIpldEF52qJSMVgVa,MJ87sN yQBCqF6g0abn5f7,EVxEgBHm j yYO qQF 3q

Popular posts from this blog

Boo (programming language)

Rothschild family