A post by Learning Dollars software engineer Ahmed K.
If you are looking for a tutorial to sharpen your javascript using libraries like Vue.js or using firebase you’ve come to the right place, as in this article we are going to discuss how to create your own ticket scanning app using these technologies.
What’s a QR ticket
A QR ticket is a ticket that contains a unique hash corresponding to a person for example:
Jon snow – tceu5lfq0388mpbj748i34up4kn23cxk
and we put that hash into a QR code so the above hash will look something like this

so our app objective is to read this QR code and validate if it exists in our database.
Requirements :
- Node js https://tecadmin.net/install-nodejs-with-nvm/
- Vue.js CLI Tool https://cli.vuejs.org/
- vue-qrcode-reader https://github.com/gruhn/vue-qrcode-reader#installation
- firebase https://cli.vuejs.org/guide/deployment.html#firebase
First Step: Create your firebase project!
You’ll need to visit your firebase console page https://console.firebase.google.com/ and then create a new project

I choose my project to be ‘ticketapp’ your dashboard will look something. After this, enable firestore and hosting in your dashboard.

Under the database tab let’s create a tickets collection and after that let’s add our attendees’ information.


Second Step: Setup our coding environment
ahmmkh@ahmmkh:~$ mkdir ticketapp
ahmmkh@ahmmkh:~$ cd ticketapp/
ahmmkh@ahmmkh:~$ vue create ticketapp
Vue CLI v3.2.2
┌───────────────────────────┐
│ Update available: 3.4.0 │
└───────────────────────────┘
? Please pick a preset: (Use arrow keys)
❯ default (babel, eslint)
Manually select features
You might have to wait a couple of minutes until you see this message:
🎉 Successfully created project ticketapp.
👉 Get started with the following commands:
$ cd ticketapp
$ npm run serve
Then let’s install vue-qrcode-reader
ahmmkh@ahmmkh:~/ticketapp$ npm install vue-qrcode-reader
and then firebase
ahmmkh@ahmmkh:~/ticketapp$ npm install -g firebase-tools
ahmmkh@ahmmkh:~/ticketapp$ npm install --save @firebase/app @firebase/firestore
ahmmkh@ahmmkh:~/ticketapp$ firebase login
After you’ve logged in to your google account, initialize your firebase project by typing
ahmmkh@ahmmkh:~/ticketapp$ firebase init
and follow these steps:
Under the src/ directory add firebase.js you can get this information from your firebase dashboard

in the App.vue file under src/ directory we change the code to this .
This is the template for our QR component.
the first part is the HTML template and we use the <qrcode-stream> component from vue-qrcode-reader library , @decode is a variable for a function that executes once a QR is detected
<template>
<div>
<p class="decode-result">Last result: <b>{{ result }}</b></p>
<qrcode-stream :camera="camera" @decode="onDecode" @init="onInit">
<div v-show="cameraForzen" class="validation-layer">
<div class="validation-notice" v-if="validating">
Long validation in progress...
</div>
<div class="validation-result" v-if="!validating">
<div v-if="isValid" class="valid">
Valid ticket
</div>
<div v-else class="invalid">
Not a valid ticket
</div>
</div>
</div>
</qrcode-stream>
</div>
</template>
under methods in the code, there is onDecode function simply what this function do is stopping the camera and validate the content and wait 2 seconds so the user can see the ticket state and after that
async onDecode (content) {
this.result = content
this.stopCamera()
this.validating = true
this.isValid = await this.validate(content)
this.validating = false
window.setTimeout(() => {
this.startCamera()
}, 2000)
}
the validate function is meant to communicate with firebase database (firestore) to get a reference for the collection you have made previously when setting up your firebase project you just need to use collection() function and then you can query it with where() function the result is a snapshot from the database so if the query returns something that means the ticket is valid and vice versan
validate (content) {
return firestore
.collection("tickets")
.where("ticketid", "==", content)
.get()
.then(snapshot => {
return new Promise(resolve => {
if (!snapshot.empty) {return resolve(true)}
else{return resolve(false)}
});
});
}
It might take a while before the component is ready and the scanning process starts. The user has to be asked for camera access permission first and the camera stream has to be loaded. this function catch these type of errors
async onInit (promise) {
this.loading = true
try {
await promise
} catch (error) {
// eslint-disable-next-line
console.error(error)
} finally {
this.firstLoad = false
this.loading = false
}
}
After that, we add some imports in our main.js file under src/ directory
import Vue from 'vue'
import App from './App.vue'
import VueQrcodeReader from "vue-qrcode-reader";
Vue.use(VueQrcodeReader);
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
Let’s now run our app:
ahmmkh@ahmmkh:~/ticketapp$ npm run serve


thank you sir, it’s helpful