Tinder Style Movie Night Picker with VueJs, Vuetify, VuexFire, and Firebase
By: Diligent Dev
Tags: JavaScript, Software Development, Vuejs, Firebase, Programming

Tinder Style Movie Night Picker with VueJs, Vuetify, VuexFire, and Firebase

Part 5 — Matches & App Polish

Image by David Mark from Pixabay

In part 4 we got movies flowing into our application and allowed the user to thumb them up or down. We also checked to see if their partner had any matches on the movies they thumbed up. The last thing we need to do is display those matches on another page and polish up the app a bit.

Matches and Vuexfire

To display the matches we’re going to be using VuexFire. This will give us real-time functionality on our matches page without having to write extra code. To do this, head to src/store/modules/user.js. At the top of the file, add the following imports:

import { firestoreAction } from "vuexfire";

import { db } from "../../main";

Then add a new state property called matches and set it to an empty array:

const state = {

id: null,

name: null,

email: null,

partnerId: null,

movieApiPage: 1,

matches: [],

};

Next, create a new action called bindMatchesRef:

bindMatchesRef: firestoreAction((context) => {

return context.bindFirestoreRef(

"matches",

db

.collection("users")

.doc(context.state.id)

.collection("matches")

);

}),

After that, head over to src/store/index.js. In there we’ll need to add a new import at the top:

import { vuexfireMutations } from "vuexfire";

Now we’ll add that to our base store mutations with object destructuring:

mutations: {

...vuexfireMutations,

}

The last thing we need to do is call the new action we added in the Vuex user module. To do so, head over to src/views/Home.vue and call the action from our created Vue lifecycle:

created() {

this.$store.dispatch("user/bindMatchesRef");

this.fetchMovies(this.userMovieApiPage);

}

Now that we’ve set that all up, our matches will update in real-time on our matches page we’re about to create.

Matches Page

Now to display the matches, head over to src/views and create a new file named Matches.vue. Inside of here, we will display the user's matches and the details of each movie. The only thing we’ll need is access to the matches collection in Firestore.

Since VuexFire will take care of syncing the data with our store, all we need to do is create a computed property to reference it:

computed: {

matches() {

return this.$store.state.user.matches;

},

},

We’ll also create a methods prop to and a method called getMovieImage to grab the poster image of the match:

methods: {

getMovieImage(posterPath) {

return posterPath ?

`https://image.tmdb.org/t/p/w500/${posterPath}` :

"";

},

}

To display the matches, we’ll loop through them and create a card for each one. Inside the card will be the title, description, and image. Your final Matches.vue file should look like this:

Navigation

Our app now has quite a few pages, but there is no way for users to navigate to them without knowing their path. To fix this, we’ll create a navigation drawer with all the pages. To do this we’re going to move the v-app-bar into its own component and add a v-navigation-drawer.

In src create a new folder called components. Then, create a file in this folder name AppBar.vue. Next, import and register this component in src/App.vue, copy the v-app-bar, and replace it with your imported component.

Back in AppBar.vue we’ll add a v-navigation-drawer with a v-list-item for each page in our app. We’ll need to add an options API data property with a drawer property to control the showing and hiding of our drawer. And, lastly, we’ll add a v-app-bar-nav-icon to toggle our drawer property. This will only be shown if a user is logged in.

After all of that, your AppBar.vue file should look like this:

AppBar.vue

Logging Out the User

Logout Button

The last thing we’ll implement is a logout feature for the users. To do so we’ll also be editing the AppBar.vue component. Right after our Movie Night Picker title add a v-spacer and v-btn. We’ll give the button text of logout, bind to the click event for a method we’ll create later, and only show the button if a user is logged in.

<v-app-bar app color="primary" dark>

<v-app-bar-nav-icon @click.stop="drawer = !drawer" v-if="userId">

</v-app-bar-nav-icon>

<div class="d-flex align-center">

<h2>Movie Night Picker</h2>

</div>

<v-spacer></v-spacer>



<v-btn text v-if="userId" @click="logoutUser">Logout</v-btn>

</v-app-bar>

Vuex

Inside of our Vuex store, we’ll need to clear the state of the user on logout. To do so we’ll need a new mutation and action in our user's module:

//action

clearUserData(context) {

context.commit("CLEAR_USER_DATA");

} //mutation

CLEAR_USER_DATA: (state) => {

state.id = null;

state.name = null;

state.email = null;

state.partnerId = null;

state.movieApiPage = 1;

}

Logout Method

Now, back inside of our AppBar.vue file, we’ll need to create our method to logout the user. At the top of the script tag, import firebase:

import firebase from 'firebase';

Then, write the function that will sign out the user, clear the user's state, and redirect back to our sign-in page.

methods: {

async logoutUser() {

await firebase.auth().signOut();

this.$store.dispatch("user/clearUserData");

this.$router.replace("/");

},

}

Video Tutorial

Video Tutorial

Conclusion

And, that's going to wrap it up for the Tinder-style movie night picker. There are a lot of improvements you can make to the application and make sure to share them if you do. If you have any comments, questions, or concerns, be sure to leave a response. Until next time, Happy Coding!