2

I am trying to create profile page for users.

I created login/register pages and I am using firebase auth. When I tried to fetch users data, everything works fine but if the profile page is reloaded, I can not see any data. (I need to go somewhere else first, then come back profile page, everything is ok again.)

I am using vue.js, kinda new in both technologies.

I tried to understand lifecycles (& also tried every options) but I could not solve the problem.

<template>
<div>
    <h2>Profile</h2>
    <h6><b>User Name:</b> {{details.name}} </h6>
    <h6><b>User Email:</b> {{details.email}} </h6>
    <h6><b>User photoUrl:</b> {{details.photoUrl}} </h6>
    <h6><b>User uid:</b> {{details.uid}} </h6>
    <h6><b>User EmailVerified:</b> {{details.emailVerified}} </h6>
</div>
</template>

<script>
import firebase from 'firebase'

    export default {
        data() {
            return {
                user: firebase.auth().currentUser,
                details: {
                    name: '', 
                    email: '', 
                    photoUrl: '', 
                    uid: '', 
                    emailVerified: ''
                }
            }
        },
        created(){
            if(this.user){
                console.log('There is a user')
                this.details.name = this.user.displayName,
                this.details.email = this.user.email,
                this.details.photoUrl = this.user.photoURL,
                this.details.emailVerified = this.user.emailVerified,
                this.details.uid = this.user.uid

            } else {
                console.log('No user')
            }
        },
        methods: {

        },
    }
</script>
2
  • Have you tried to use mounted instead of created? Commented Sep 28, 2018 at 8:33
  • @ThomasLombart Yes, It acts like created (same results) Commented Sep 28, 2018 at 8:36

2 Answers 2

3
   <template>
<div v-if="user">
    <h2>Profile</h2>
    <h6><b>User Name:</b> {{user.displayName}} </h6>
    <h6><b>User Email:</b> {{user.email}} </h6>
    <h6><b>User photoUrl:</b> {{user.photoUrl}} </h6>
    <h6><b>User uid:</b> {{user.uid}} </h6>
    <h6><b>User EmailVerified:</b> {{user.emailVerified}} </h6>
</div>
</template>


 <script> import firebase from 'firebase'

    export default {
        data() {
            return {
                user: null
                }
            }
        },
        created(){
        firebase.auth().onAuthStateChanged(function(user) {
          if (user) {
                this.user = user
             } else {
                console.log('No user')
                this.user = null
                }
              });

        },
        methods: {

        },
    } </script>

The recommended way to get the user is via the listener, also described more in depth here https://firebase.google.com/docs/auth/web/manage-users

I also edited your code to make your code less with the same result.

Sign up to request clarification or add additional context in comments.

4 Comments

It worked perfectly, I guess main problem stems from using this line "user: firebase.auth().currentUser," in data() part. What do you think ?
I said that it worked but now I checked the console there is an error. (I can see all data on the screen but the error on the console prevents to add something else.) [Vue warn]: Error in render: "TypeError: Cannot read property 'displayName' of null"
@CanerSezgin Im at work so i cant reproduce it, could you try to not render the content before the user is actually populated via the v-if statement i edited in my post above. Hit me up with your results
Thank you so much,
1

I usually keep the initial firebase auth state logic outside of the Vue instance (but then use vue methods as usual for page interaction after load).

Initialise your vue data user object with the keys you intend to use, and look for user uid (since all users will have this including anonymous users) for v-if.

You could also make sure onAuthStateChanged has executed before the user data is updated (can't remember if you can assume that it will have executed before the vue instance is created or not, but this will make sure you don't not load user data that becomes present after the vue instance is created just in case) by having a boolean (e.g. authChecked) changed from false to true when onAuthStateChanged has executed, and using a method (that is used in 'created') that runs itself again and again using setTimeout if authChecked isn't true yet.

All of this (and some other slight additions below) will ensure you only display data you have, won't get the error you had, and will load the user data if firebase happens to retrieve it after the vue instance is created e.g.

<template>
    <div v-if="user.uid">
        <h2>Profile</h2>
        <h6 v-if="user.displayName"><b>User Name:</b> {{user.displayName}} </h6>
        <h6 v-if="user.email"><b>User Email:</b> {{user.email}} </h6>
        <h6 v-if="user.emailVerified"><b>User EmailVerified:</b> {{user.emailVerified}} </h6>
        <h6 v-if="user.photoUrl"><b>User photoUrl:</b> {{user.photoUrl}} </h6>
        <h6><b>User uid:</b> {{user.uid}} </h6>
    </div>
</template>

<script>
import firebase from 'firebase'

const auth = firebase.auth()
var authChecked = false;

var user = auth.onAuthStateChanged(function(user) {
    if(user) {
        return user
    } else {
        return null
    }
    authCkecked = true;
})

export default {
    data() {
        return {
            user: {
                displayName: ""
                email: ""
                emailVerified: "" 
                photoUrl: ""
                uid: ""
            }
        }
    },
    created() {
        this.updateUser;
    },
    methods: {
        updateUser() {
            if (authChecked) {
                if (user) {
                    this.user = user
                } else {
                    console.log('No user')
                }
            } else {
                setTimeout(this.updateUser, 200)
            }
        }
    }
}
</script>

2 Comments

Thank you for your contribution but I did not understand why I should use this method instead of Badgy's one. Could you explain please ?
As far as I'm aware, it's possible that firebase may not have initialised by the time the created lifecycle hook on the vue instance is called which could cause additional errors. My adaptation makes sure that you don't attempt to update the user data until firebase has been initialised and subsequently checked for an authenticated user.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.