2

I am implementing Twitter authentication using FirebaseUI in my Vue.js app.

While I can successfully authenticate the user, I can't figure out how to store info from the AuthResult object.

In my parent component (App.vue), I listen for the onAuthStateChanged event to save the user details. This works well, but the user object doesn't contain API credentials returned by Twitter.

firebase.auth().onAuthStateChanged((user) => {
  if (user) {
    this.user = user
    this.$router.push('/user')
  } else {
    this.$router.push('/login')
  }
})

Those credentials are contained in the firebaseui.auth.AuthResult object, which is accessible in the FirebaseUI callback named signInSuccessWithAuthResult.

The problem I am facing is that I cannot call Vue.js functions from within this callback - I can't modify data using this.foo, I can't emit an event either with this.$emit. I can console.log() the authResult object, but that's about it.

Q: How can I save the authResult object in my Vue app?

For clarity, here is my child Login component (template simplified):

<template>
   <div>
      <div id="firebaseui-auth-container"></div>
   </div>
</template>

<script>
import firebase from 'firebase'
import * as firebaseui from 'firebaseui'
export default {
  name: 'Login',
  data () {
    return {
      foo: ''
    }
  },
  mounted () {
    var uiConfig = {
      signInOptions: [
        firebase.auth.TwitterAuthProvider.PROVIDER_ID
      ],
      signInFlow: 'popup',
      callbacks: {
        signInSuccessWithAuthResult: function (authResult) {
          // this.$emit('updateAuthResult', authResult)
          // this.foo = 'bar'
          console.log(authResult)
          return true
        }
      }
    }
    var ui = new firebaseui.auth.AuthUI(firebase.auth())
    ui.start('#firebaseui-auth-container', uiConfig)
  }
}
</script>

2 Answers2

2

Isn't it a problem of context? See When to Use vm. or this. in Vue.js

What happens if you do:

mounted () {
    var vm = this
    var uiConfig = {
      signInOptions: [
        firebase.auth.TwitterAuthProvider.PROVIDER_ID
      ],
      signInFlow: 'popup',
      callbacks: {
        signInSuccessWithAuthResult: function (authResult) {
          vm.$emit('updateAuthResult', authResult)
          vm.foo = 'bar'
          console.log(authResult)
          return true
        }
      }
    }
    var ui = new firebaseui.auth.AuthUI(firebase.auth())
    ui.start('#firebaseui-auth-container', uiConfig)
  }
Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121
1

I think you can use an arrow function to resolve this problem

mounted () {
 var uiConfig = {
  signInOptions: [
    firebase.auth.TwitterAuthProvider.PROVIDER_ID
  ],
  signInFlow: 'popup',
  callbacks: {
    signInSuccessWithAuthResult: (authResult) => {
      this.$emit('updateAuthResult', authResult)
      console.log(authResult)
      return true
    }
  }
 }
 var ui = new firebaseui.auth.AuthUI(firebase.auth())
 ui.start('#firebaseui-auth-container', uiConfig)
}
  • You are probably right - it's been a while and I don't have the original project at hand but an arrow function should also solve the `this` issue. – Jonáš Jančařík Apr 06 '20 at 12:03