Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auth examples #47

Closed
ryanmclaughlin opened this issue Nov 13, 2016 · 10 comments
Closed

Auth examples #47

ryanmclaughlin opened this issue Nov 13, 2016 · 10 comments

Comments

@ryanmclaughlin
Copy link

ryanmclaughlin commented Nov 13, 2016

Hi there,

I'm having trouble getting auth to work. I have successfully implemented the ability to create and login to an account, but I'm having trouble getting the currentUser with the function onAuthStateChanged.

Does anyone have any Vue 2.0, vue-router, and Firebase 3+ examples of auth successfully implemented that would steer me in the right direction?

/views/Auth.vue

<script>
  import firebase from '../services/firebase.js'

  export default {
    data() {
      return {
        email: '',
        password: '',
        confirmPassword: '',
        wantsToSignUp: false,
        errorMessage: '',
      };
    },
    methods: {
      signUpWithPassword() {
        if (this.password === this.confirmPassword) {
          firebase.auth.createUserWithEmailAndPassword(this.email, this.password)
          .then(() => this.signInWithPassword())
          .catch((error) => { this.errorMessage = error.message });
        }
      },
      signInWithPassword() {
        return firebase.auth.signInWithEmailAndPassword(this.email, this.password)
        .then((userData) => {
          this.onSignedIn();
          return userData;
        })
        .catch((error) => { this.errorMessage = error.message });
      },
      onSignedIn() {
        this.$router.go('/');
      },
    },
  };
</script>

AppNav always reports unknown user.title after I am logged in.

/components/AppNav.vue

<script>
  import firebase from '../services/firebase.js'

  export default {
    data() {
      return {
        user: null,
        searchQuery: '',
      };
    },
    methods: {
      processUser(authed) {
        console.log(authed);
        if (authed === null) {
          this.user = null;
          return;
        }
        this.user = {
          title: authed.email || '',
        };
      },
      signOut() {
        firebase.auth.signOut();
        this.$router.go('auth');
      },
    },
    ready() {
      firebase.auth.onAuthStateChanged(this.processUser);
      this.processUser(firebase.auth.currentUser);
    },
  };
</script>
@chrisbraddock
Copy link

chrisbraddock commented Nov 18, 2016

I would try making user a computed property. Also maybe test this.$nextTick() after assigning user. Throw a <pre>{{ user }}</pre> in your UI and/or see what the DevTools plugin says. Is there a binding getting clobbered when you overwrite this.user in processUser? Try initializing user to an empty object and only assigning the title property in processUser.

I'm having success so far with auth and vuefire. If you're still stuck after the above I can make a Plnkr or something.

I start .auth() in beforeCreate vs. ready. I try to get it going as soon as possible. I'm only using anonymous auth at the moment though. I don't have any UI attached to the process.

@ryanmclaughlin
Copy link
Author

ryanmclaughlin commented Nov 18, 2016

Hey @chrisbraddock I've gotten it to work so far. Now I'm stuck with another problem of needing the currentUser.uid to before rendering the UI and I'm not sure to go about that. It's a different issue though so I'll close this for now. If you have ideas however, a Plnkr would be great; no biggie if not though.

@chrisbraddock
Copy link

chrisbraddock commented Nov 18, 2016

Ooh haha yeah I'm in the midst of a refactor on that very thing right now.

Basically, any refs that need a user I'm waiting for authStateChanged (or more specifically userAuthenticated - my custom event I $emit on $root after authStateChanged if user isn't null).

Once you get the event you can $vm.$bindAsArray or $bindAsObject manually. See vuefire.js $bindAsArray and ultimately vue/src/core/observer/index.js defineReactive().

Depending on what you're doing, data fetching before navigation might be worth looking at, assuming you're using vue-router.

BTW, you say 'before rendering the UI'. I read that in the context of the problem I'm in the middle of. Do you mean, you're unable to setup the Firebase reference(s) for a particular component because the user uid is in the database paths? That's the issue I've encountered. You should be able to set typical reactive properties on the $vm in data() and init them to empty objects/arrays and let the UI load up (sans that data) then the subsequent $bindAsArray|Object will take care of the update when you have the database references.

@ryanmclaughlin
Copy link
Author

ryanmclaughlin commented Nov 18, 2016

I've looked into the waitForData: true feature and couldn't get it to work, even if I try forcing a return of false. I'll keep playing with it.

Yes that's what I mean. I'm using onAuthStateChanged in my nav bar and in a movie list component. I have users and movies and I'm needing the currentUser.uid to grab the users/{uid}/movies/ and it's not getting fetched in time, and when it does, it still won't re-render, despite having them in data() and vuefire firebase.

Example:

  const moviesRef = firebase.db.ref('movies');
  const usersRef = firebase.db.ref('users');

  export default {
    components: {
      Movie,
    },
    firebase: {
      movies: moviesRef,
      users: usersRef
    },
    data() {
      return {
        uid: '',
        users: '',
        movies: '',
      }
    },
  }

@chrisbraddock
Copy link

see if this helps: https://github.com/chrisbraddock/vuefire-auth-demo

@ryanmclaughlin
Copy link
Author

see if this helps: https://github.com/chrisbraddock/vuefire-auth-demo

Thanks! I couldn't find where we were chatting back and forth for some reason >.<

That was helpful, especially now I know how to use this.$bindAsArray in context.

@chrisbraddock
Copy link

I was able to swap vuefire for vuexfire really easily. I'm testing that as a full blown solution now.

@ryanmclaughlin
Copy link
Author

I was able to swap vuefire for vuexfire really easily. I'm testing that as a full blown solution now.

Ah sweet! This is exactly what I'm attempting to do now. I got it workout without modules, but I feel like I may need them.

Fyi, I'm on https://gitter.im/vuejs/vue

@willwillems
Copy link

Hey I know that this is closed and Chris thanks for the Auth example but did any of you happen to get this working in components? I'm importing a firebase function in every component so doing a bunch of this.$bindAsArray in every component plus defining the data placeholders there would be awful.

Thanks!

@chrisbraddock
Copy link

@NickolasBoyer, sorry for the late reply. You might check out Vuex and Vuexfire. Assuming the state you're talking about needing "in every component" is shared state, Vuex is a good place to house that, and getting that data in to components is simple using Vuex mapState and mapGetters.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants