Ryan
Ryan

Reputation: 125

Twitter Authentication with Vue, Vuex and Firebase

I've been trying to use a Twitter login option for a sports social media dashboard that I am trying to dissolve. I have been following this helpful tutorial I have scraped the HelloWorld component and have kept the app.vue and main.js component. Below is my code. I am receiving the error 'router not defined'. This may just be a routing issue. I have both the Twitter app and Firebase authentication correct. Any thoughts? Thanks

firebaseConfig.js

const firebaseConfig = {
  apiKey: "AIzaSyBaWJ2p6TDNq1WuOVLLtjsJq1xDypaXqdM",
  authDomain: "sportlydatabase.firebaseapp.com",
  databaseURL: "https://sportlydatabase.firebaseio.com",
  projectId: "sportlydatabase",
  storageBucket: "sportlydatabase.appspot.com",
  messagingSenderId: "287835560944",
  appId: "1:287835560944:web:46024fe79c1d870531db35",
  measurementId: "G-48VM19JE6M"
};

sign.vue

 <template>
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-6">
                <h3>Sign In with Twitter</h3>
                <button class="btn btn-primary"
                    @click="signIn">
                    <i class="fa fa-twitter"></i>
                    SignIn with Twitter
                </button>
            </div>
        </div>
    </div>
</template>


<script>
export default {
    methods: {
        signIn () {
            this.$store.dispatch('signIn')
        }
    }
}
</script>

<style scoped>
h3 {
    font-weight: 700;
}
button {
    background-color: #1dcaff;
    border: 1px solid  #1dcaff;
}
div button:hover {
    background-color: #00aced;
    border: 1px solid  #00aced;
}
</style>

Home.vue

    <template>
    <div container-fluid>
        <div>
            <h2>Welcome {{ user.userDetails[0].displayName }}

            </h2>
            <p>You are logged in</p>
            <img :src="user.userDetails[0].photoURL" alt=""
                class="img-circle" height="100px" width="100px"
            >
        </div>
    </div>
</template>


<script>
export default {
    computed: {
       user () {
           return this.$store.getters.user
       }
    }
}
</script>

<style scoped>
h2 {
    font-weight: 700
}
</style>

store.js

  import Vue from 'vue'
import Vuex from 'vuex'
import firebase from 'firebase'

Vue.use(Vuex)

export const store = new Vuex.Store({
    state: {
        user: null
    },
    getters: {
        user (state) {
            return state.user
        }
    },
    mutations: {
        SET_USER (state, payload) {
            state.user = payload
        },
        LOGOUT (state, payload) {
            state.user = null
        }
    },
    actions: {
        autoSignIn({ commit }, payload) {
            const newUser = {
                userDetails: payload.providerData
            }
            commit('SET_USER', newUser)
        },
        signIn({ commit }) {
            var provider = new firebase.auth.TwitterAuthProvider();
            firebase.auth().signInWithRedirect(provider);
            firebase.auth().getRedirectResult().then(result => {

                // The signed-in user info.
                var user = result.user;
                commit('SET_USER', user)
            }).catch(error => {
                alert(error)
                return 
            })
        },
        logout({ commit }) {
            firebase.auth().signOut().then(function () {
                commit('LOGOUT')
            }).catch(function (error) {
                alert(error)
                return
            });
        }
    }
})

index.js

  router.beforeEach((to, from, next) => {
  const currentUser = firebase.auth().currentUser;
  const requiresAuth = to.matched.some(record => record.meta.requiresAuth);

  if (requiresAuth && !currentUser) {
    next('/');
  }
  else if (!requiresAuth && currentUser) {
    next('/home');
  }
  else {
    next();
  }
});

export default router

main.js

    // The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue';
import App from './App';


Vue.config.productionTip = false;

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>',
});

Upvotes: 0

Views: 428

Answers (1)

Renaud Tarnec
Renaud Tarnec

Reputation: 83068

It seems that you need to modify your main.js file as follows:

import Vue from 'vue';
import App from './App';
import router from './router'

See the main.js file from your tutorial: https://github.com/chuks-o/twitterauth/blob/master/src/main.js. Note that we do from './router' because your router index.js file is under a specific router directory.

Upvotes: 1

Related Questions