io2015-codelabs icon indicating copy to clipboard operation
io2015-codelabs copied to clipboard

Firebase codelab oauth does not trigger child_added

Open wgittoes opened this issue 9 years ago • 2 comments
trafficstars

Was going through this codelab: https://codelabs.developers.google.com/codelabs/cloud-firebase-chat/index.html#5

It stopped working once I added the security rules (".read": "auth != null").

The reason why seems to be that it tries to run all the child_added events on page load or soon after, and fails since auth is not present. Then the user authenticates using the popup, but the child_added events are not retried and the page remains empty of new 'messages'.

If the auth 'remember' is switched to 'sessionOnly', then I can reload the page and it works - the auth is already present when those child_added events come in and it all works. However, the code as presented in the codelab does not work.

wgittoes avatar Mar 08 '16 06:03 wgittoes

If the child_added callback is added after auth, then it works.

<script>
  var myFirebase = new Firebase('https://____________.firebaseio.com/');
  var username = null;
  var loginButton = document.querySelector('#login');
  var textInput = document.querySelector('#text');
  var postButton = document.querySelector('#post');
  postButton.style.display = "none";
  textInput.style.display = "none";

  var startListening = function() { // <------------------------- Do not add listener yet!!
    myFirebase.on('child_added', function(snapshot) {
      var msg = snapshot.val();
      var msgUsernameElement = document.createElement("b");
      msgUsernameElement.textContent = msg.username;
      var msgTextElement = document.createElement("p");
      msgTextElement.textContent = msg.text;
      var msgElement = document.createElement("div");
      msgElement.appendChild(msgUsernameElement);
      msgElement.appendChild(msgTextElement);
      msgElement.className = "msg";
      document.getElementById("results").appendChild(msgElement);
    });
  };

  postButton.addEventListener("click", function() {
    var msgUser = username;
    var msgText = textInput.value;
    myFirebase.push({username:msgUser, text:msgText});
    textInput.value = "";
  });

  loginButton.addEventListener("click", function() {
    myFirebase.authWithOAuthPopup("google", function(error, authData) {
      if (error) {
        console.log(error);
      } else {
        console.log(authData);
      }
    }, {remember: "none"}); // will end authentication on page close/reload
  });

  myFirebase.onAuth(function (authData) {
    if (authData) {
      username = authData.google.displayName;
      loginButton.textContent = "Logged in as " + username;
      loginButton.disabled = true;
      postButton.style.display = "block";
      textInput.style.display = "block";
      startListening();  // <-------------------------------------- Add listener now
    }
  });
</script>

wgittoes avatar Mar 08 '16 06:03 wgittoes

@wgittoes thank you for the detailed report. I believe you are correct that there is a bug in this codelab. Firebase listeners only check auth state once: when they are created. So if you create a listener to an authenticated path when you are unauthenticated it will never return data, even if you later authenticate.

samtstern avatar Mar 08 '16 18:03 samtstern