#vuefire tutorial
Explore tagged Tumblr posts
Photo

VueFire: CRUD Application with Vue.js and Firebase VueFire: CRUD Application with Vue.js and Firebase Want to learn how to integrate Firebase and Vuefire into your Vue.js applications? This video does just that ... source
#application#crud#firebase#vue crud#vue crud firebase#vue fire#vue firebase crud#vue firebase example#vue firebase tutorial#vue tutorial hello world#vue.js firebase#vue.js vuefire#vuefire#vuefire tutorial#vuefire vuejs#VueFire: CRUD Application with Vue.js and Firebase#vuejs#vuejs firebase#vuejs firebase tutorial
0 notes
Text
VueJS & Firebase Cloud Firestore Stripped-Back - Tutorial Part 2
In this tutorial series we are using a stripped-back approach to getting started with Vuejs & Firebase Cloud Firestore to build full-stack web applications. No CLIs or build tools just a HTML page.
Putting the ‘C’ in CRUD
Welcome back to our Vue and Firebase stripped back tutorial. If you skipped part 1 of this tutorial you can get it here.
Let’s start straightaway from where we left off in part 1 and start looking at how we can develop our employee tracker app, EmployeeMagic, to let the user add records to their employee database. This represents the C in CRUD (Create, Read, Update, Delete).
We’ll start by adding some input boxes to our template for the user to be able to add employees. The fields we want are first and last names, job title, department and age.
Let’s start by adding a First Name field.
<body>
<div id=“app”>
<div v-bind:style=“mainStyle”>
<h1>{{ appTitle }}</h1>
<label>First Name</label> <input type=“text” v-model=“firstName”>
</div>
</div>
</body>
Notice the input element, we’ve added a Vue directive to it called v-model and we’ve assigned it a value of firstName. For AngularJS devs this will seem very familiar. v-model is a data binding directive that binds the input element to a variable in our view model (the data in the Vue Instance Object). Therefore whatever value the user keys into the input box will be automatically assigned to a variable in your Vue Instance Object. Now we don’t presently have a firstName variable in data in our Instance Object so we need to add it and assign it an initial value, in this case an empty string.
<script> var app = new Vue({ el : '#app’, data : { appTitle : ‘EmployeeMagic’, mainStyle : { ‘margin’ : ’20px’ }, firstName : ‘’ } }) </script>
Just to prove that our data-binding in Vue is working and is in fact working in both directions (from the template to the Instance Object and from the Instance Object to the template), also called two-way data binding, we’ll stick a double-curly on the end of the input box eg
<input type=“text” v-model=“firstName”>{{ firstName }}
Save the file and refresh the page in your browser. As you begin to type in the First Name box, the name is displayed at the side of it. The input is assigning it to the firstName variable (via the v-model directive) and Vue is watching for changes in the firstName variable and when it detects one it changes anywhere in the page where firstName has a binding, in this case via the double-curly.
OK, enough of the fun and games, let’s add our other fields to the template and create their corresponding variables in the data section. As we’re grouping several fields together to form an employee we’ll change it to put them all in their own object called employee and change the template to bind the input boxes to the relevant properties on the employee object instead. We’ve proved our point with the two-way data binding for now so we’ll remove our double curly.
<body>
<div id=“app”>
<div v-bind:style=“mainStyle”>
<h1>{{ appTitle }}</h1>
<label>First Name</label> <input type=“text” v-model=“employee.firstName”></br>
<label>Last Name</label> <input type=“text” v-model=“employee.lastName”></br>
<label>Job Title</label> <input type=“text” v-model=“employee.jobTitle”></br>
<label>Dept.</label> <input type=“text” v-model=“employee.dept”></br>
<label>Age</label> <input type=“number” v-model:number=“employee.age”></br>
</div>
</div>
</body>
Notice that on the Age input we’ve added an extra command to the v-model directive, :number. This is very useful in Vue as, although the type of the input is set to number so the user cannot input anything other than valid numbers, by default when the value is converted by the binding to Vue data properties, it is converted as a string. As we want the age property to remain a number type, the v-model:number directive is required. <script> var app = new Vue({ el : '#app’, data : { appTitle : ‘EmployeeMagic’, mainStyle : { ‘margin’ : ’20px’ }, employee : {firstName : ‘’, lastName : ‘’, jobTitle : ‘’, dept : ‘’, age : 0 } } }) </script> We’ll next add a Save button which will write the entered employee to the database. To carry out the task of saving when the user clicks the Save button we need to hook the button into our Vue Instance Object and call a function that’s run to save our new employee record. To do this we need to use another Vue directive called v-on:click
<label>Age</label> <input type=“number” v-model:number=“employee.age”></br>
<button v-on:click=“saveEmployee()”>Save</button>
</div>
</div>
</body>
v-on is used to handle events and the :click is the specific event to be triggered on. We then assign the function that we want to run once the event (click) is triggered, in this case saveEmployee().
If you remember, in part 1 of this tutorial we mentioned that when using the v-bind directive along with a colon-command that you could use shorthand instead by dropping the v-bind eg v-bind:style could be entered as just :style for short. The same applies to the v-on directive however as it’s an event, rather than using the colon, you must use a @ instead. Therefore instead of using v-on:click you could use the shorthand version which is @click. Ultimately it’s a matter of preference and usually I would use the shorthand but to provide full explanations in these tutorials we’ll stick to using the verbose style.
We now need to write our saveEmployee() click handler function. This involves declaring functions or methods in our Vue Instance Object which you can do by declaring a new first-level object on the Instance Object called methods. All of your logic for our app will live in functions declared in Vue’s methods object. <script> var app = new Vue({ el : '#app’, data : { appTitle : ‘EmployeeMagic’, mainStyle : { ‘margin’ : ’20px’ }, employee : {firstName : ‘’, lastName : ‘’, jobTitle : ‘’, dept : ‘’, age : 0 } }, methods : { saveEmployee : function() { alert(‘You have saved ‘ + this.employee.firstName + ‘ ‘ + this.employee.lastName) } } }) </script> So, you can see that we’ve declared a saveEmployee function within the top-level methods object. In the above we’re not saving anything, we’re just going to display a standard alert message which includes displaying the last name and first name of the employee we’re saving. Notice that we’re using this to refer to our employee properties. Any variable declared in the data object of our Instance Object that we want to reference in our methods must be referenced using this, otherwise Vue won’t recognise it. As anyone who has worked with Javascript for any length of time knows, using this can be problematic as what it points to can change depending on the context from where it was called. There are ways around using this which we’ll discuss later but we’ll just stick with it as it is for now. Save the file, refresh your browser and enter the details of an employee, click Save and you should see the alert message appear. We’re now at the point of needing to be able to physically save our new employee to our Firebase Cloud Firestore. To get started with this you just need a bog-standard Google account. If you’ve got a gmail account or use any of Google’s products where you need to log-in then you’ve got a Google account. If not then you’ll need to create one which you can do on the Firebase site. To get started go to the Firebase web-site (https://firebase.com) and click Go To Console. If you’re not signed in to your Google account or you don’t have one you’ll then be taken to the usual sign-in/sign-up pages to get going, otherwise you’ll be taken to the Firebase console. Click Add Project and enter a project name and select your region. Once in the main console click the Database option on the left. You’ll be given the option of Realtime Database or Cloud Firestore. Make sure you select Cloud Firestore. You’ll also be asked how you want the security level to be setup, make sure you select Development/Test mode otherwise you’ll have to start setting up security rules manually which are a whole other subject altogether. Your Cloud Firestore will then be setup, which might take a short while. Once your database is setup we don’t need to do anything else in the database console however we do need to grab the code and libraries for getting Firebase into our app. To do this click the Project Overview option on the left. In the Get Started page click on the option for Add Firebase to your web app. In the window that pops up you’ll see a code snippet, just click the Copy button. Go back to your editor and paste the code snippet below the closing </body> tag and above the VueJS CDN script tag as shown below : </body>
<script src="https://www.gstatic.com/firebasejs/4.9.1/firebase.js"></script> <script> // Initialize Firebase var config = { apiKey: "AIzaSyA0KlHuISpQL1F0XMWv1FfmtbaJQmPKwqQ", authDomain: "vuefire-da3bf.firebaseapp.com", databaseURL: "https://vuefire-da3bf.firebaseio.com", projectId: "vuefire-da3bf", storageBucket: "vuefire-da3bf.appspot.com", messagingSenderId: "1094070580435" }; firebase.initializeApp(config); </script> <script src="https://cdn.jsdelivr.net/npm/vue"></script><script> var app = new Vue({ The version of the Firebase CDN link above (4.9.1) is current at the time of writing (Feb 2018) but is likely to be different by the time you are reading this, always use the link copied from the Firebase page. This details in the config object are specific to my account and project and yours will certainly be different, make sure you keep the code exactly the same as the code snippet copied from your Firebase project. The code snippet from Firebase however doesn’t include a CDN for Cloud Firestore, this may well be due to it still being officially in beta at the time of writing and may well be included in the standard code snippet by the time you’re reading this so it’s worth checking. At this point in time however, we’ll need to add it manually and the best way to do it is just to copy the line for the firebase CDN link for firebase.js, paste it below it and change the new line from firebase.js to firebase-firestore.js as below : <script src="https://www.gstatic.com/firebasejs/4.9.1/firebase.js"></script> <script src="https://www.gstatic.com/firebasejs/4.9.1/firebase-firestore.js"></script> Save the page and refresh in Chrome with the Console open and make sure there are no errors displayed before proceeding and if there are check you have followed everything above correctly. We’ve now got our libraries for Cloud Firestore and the code snippet will initialise Firebase to enable you to utilise your newly created database. Now we have to let our Vue app know about it. What we need to do is to create a Firestore object within our Vue app when it first runs so it’s available to us throughout our app. To ensure that our Firestore object is created at the beginning during initialisation of our app, we need to utilise a lifecycle hook that Vue provides, called created. Lifecycle hooks are effectively events that occur during Vue’s internal processing of our Instance Object. Vue exposes these events to us so we can hook into them and carry out some tasks at that specific point in our Vue Instance Object’s processing lifecycle. With the created hook, we can attach the tasks we want to carry out when the Vue Instance Object is first created, which is exactly what we need to do to generate a Firestore object to ensure we can access the database throughout the app. We’ll first initialise an object in our data section called db that we’ll use to access Firestore. We’ll then include a created hook which is a function containing our initialisation code. In this case we just want to assign an object from Firestore that we can use :
<script> var app = new Vue({ el : ’#app’, data : { appTitle : ‘EmployeeMagic’, mainStyle : { ‘margin’ : ’20px’ }, employee : {firstName : ‘’, lastName : ‘’, jobTitle : ‘’, dept : ‘’, age : 0 }, db : {} }, methods : { saveEmployee : function() { alert(‘You have saved ‘ + this.employee.firstName + ‘ ‘ + this.employee.lastName) } }, created : function() { this.db = firebase.firestore() } }) </script> We’re now plugged into our Firestore through our db object. It’s now fairly straightforward to save our data to Firestore. We use Firestore’s add() function to save our employee object which, as we covered earlier, is automatically populated through data binding when the user enters the information into the input boxes. To call add() we must tell Firestore which Collection to save the new object to. Collections in Firestore represent a formal declaration of the documents or objects we’re going to save. This makes it much more like the Tables and Records we’re used to in relational databases, where tables are collections and records are documents. In this case we’ll save it to a collection called Employees - note that we didn’t explicitly setup the Employees collection previously, it will be automatically created for us by Firestore if it doesn’t already exist. We’ll remove the alert from our saveEmployee function and replace it with the line to save the new employee. methods : { saveEmployee : function() { this.db.collection(‘Employees’).add(this.employee); } }, Again notice that we’re referencing db using this, as we are with employee (and all of our data properties). We’ll review this shortly but it’s important to note it for now. Save the file in your code editor and refresh it in Chrome. Enter the details of an employee and click Save. Nothing will appear to happen on the page, however open your Firebase console, select Database and you’ll see your new record under the Employees collection. Notice that the record has a strange looking unique Id automatically assigned to it, we’ll be utilising this in another part of the tutorial. Let’s tidy up the saving process. Firstly we want to make sure it doesn’t save unless something is entered into both the First and Last Name fields. Secondly we want some visual indication that you have saved to the database, specifically the input boxes are cleared ready for another new employee. In order to clear the employee inputs we’ll implement a separate function called clearEmployee() so we’re not cluttering up our save function. methods : { saveEmployee : function() { if ((this.employee.firstName) && (this.employee.lastName)) { this.db.collection(‘Employees’).add(this.employee) clearEmployee() } else alert(‘You must enter both a first and last name to save.’) }, clearEmployee : function() { this.employee = { firstName : ‘’, lastName : ‘’, jobTitle : ‘’, dept : ‘’, age : 0 } } }, Note 2-way data binding, changing the properties in the view model reflects in the input boxes that they’re bound to. It’s important to note that Firestore’s add() function is asynchronous so any code that comes after it, such as clearing the input fields, will be executed before it can be determined if the employee was saved correctly. Therefore rather than simply call the clearEmployee() function immediately after add() as we have done above, we’ll need to utilise the promise which Firestore’s add() function returns and put any code we want to execute after it’s successfully saved into the returned promise’s then(). saveEmployee : function() { if ((this.employee.firstName) && (this.employee.lastName)) this.db.collection(‘Employees’).add(this.employee) .then(function() { this.clearEmployee() }) .catch(function() { console.log(‘Error saving employee ‘ + this.employee.firstName + ‘ ‘ + this.employee.lastName) }) else alert(‘You must enter both a first and last name to save.’) }, Here we’ve chained a then() to the add() function call and passed in a function which calls the clearEmployee() to clear the properties for the input boxes only after we’re sure of a successful save. We’ve also chained a catch() so any saving errors are logged to the console.
A brief explain of Promises
If you’re not familiar with promises, they’re simply a way to handle asynchronous code. Asynchronous functions are just standard functions which carry out some processing but return control back to the caller before completing it’s process (to avoid blocking the app’s execution). Async functions usually return a promise object which enables the code which called the function to implement any tasks that needs to execute only after the async function has fully completed it’s process. In this instance we only want to clear the input boxes once we know that the employee has definitely saved. To do this we call then() which is a function on the returned promise object. then() accepts a function as a parameter which we use to execute any code we want after we know the save has completed, in this case to clear the employee properties and inputs. As we’ve done above you can also chain a call to the promise’s catch() function to execute any code should the async function not succeed. With all of that said, the new changes we’ve just made WILL NOT WORK!! And they will not work because of the this issue that was foretold. The reference to this changes depending on the context in which it was called. Therefore when we come to execute the code that is passed to the then() or catch() functions, this points to something else other than our Instance Object data and we’ll get errors! There are a couple of ways around this. The traditional way is to simply assign this at the beginning of a function to another variable, usually called that, and then reference that instead of this throughout the function to be sure that you’ll always reference the desired object. This works but it means you’re always having to remember to implement it at the beginning of every method. The other way is to reference the Instance Object explicitly where you know this won’t work for you. In this tutorial we declared a variable to contain our Vue Instance Object called app eg var app = new Vue({. You can therefore call app.clearEmployee() instead of this.clearEmployee() in the then() function and it would work. The problem is that context again gets in the way and you cannot use an explicit reference to the Instance Object in it’s own context so saying app.db.collection(‘Employees’).add(app.employee) in the main saveEmployee() function won’t work either, so you’d end up using this in some places and app in others.
The ideal solution would enable us to use one way throughout to refer to the properties and methods on your Instance Object to ensure consistency but without additional workload that you would need to remember to implement on each method. Fortunately ES6/ES2015 introduced arrow functions which help us resolve this problem. With arrow functions we can use an explicit reference to the Instance Object in every context throughout our methods. Arrow functions, from a declarative standpoint, simply change a function declaration from : function() { }
to () => { } So let’s change our saveEmployee() function from a standard function declaration to an arrow function and do the same with the then() and catch() functions. Then replace every reference of this to app. saveEmployee : () => { if ((app.employee.firstName) && (app.employee.lastName)) app.db.collection(‘Employees’).add(app.employee) .then(() => { app.clearEmployee() }) .catch(() => { console.log(‘Error saving employee ‘ + app.employee.firstName + ‘ ‘ + app.employee.lastName) }) else alert(‘You must enter both a first and last name to save.’) }, For consistency purposes we should also change our clearEmployee() method as well clearEmployee : () => { app.employee = { firstName : ‘’, lastName : ‘’, jobTitle : ‘’, dept : ‘’, age : 0 } } The only exception to this rule is the created lifestyle hook function where the VueJS docs expressly recommends not declaring it as an arrow function so we’ll leave it as a standard function declaration (including referencing this rather than app). Like with Promises, arrow functions are a fairly new addition to JS so you must be using an evergreen browser, like Chrome, which implements them natively otherwise you’ll need to use a transpiler such as Babel. We’ve now completed the Create task from our CRUD list. In this tutorial we’ve added input boxes and bound them to properties on our view model to create 2-way data binding. We’ve added events and methods to our Instance Object, created a Firebase Cloud Firestore project and hooked it into our app, covered Vue’s lifecycle hooks to initialise a reference to our database and then covered how to save employees to our Cloud Firestore. Finally we covered the issues with using this and how arrow functions can help us overcome these problems. In the next part of the tutorial we’ll cover the R in CRUD, Reading (or Retrieving) employees from our database. We’ll cover getting data back from our Firestore and explain how to implement realtime updates. I hope you’ll join me.
You can download the completed code for this part of the tutorial on Github using the repo below and select the part2 folder. https://github.com/MancDev/VueFire
1 note
·
View note
Link
0 notes
Photo
Building With Vue.js 2 and Firebase
Introduction
Firebase is Google's mobile platform that helps you develop high-quality apps and grow your business. In this tutorial, you will make good use of one of Firebase's awesome features: the Realtime Database.
You will build a single page application to create books. This book will be saved to your Firebase database, and you will be able to retrieve and delete books you have created.
Let's get started.
Set Up Firebase
Go to Google's Firebase page to create a new account. When done with that, log in to your console. Click on the option to add a project. Enter your project details and click on the button CREATE PROJECT.
This will lead you to your console. The Firebase console helps you manage your Firebase configuration settings.
For this tutorial, you'll need to make access to your database public. From the panel on the left, select Database. Select Realtime Database from the options that show next by clicking GET STARTED. Making your database public involves editing the rules. So click RULES on the page that loads next.
Make your rules look like this.
{ "rules": { ".read": true, ".write": true } }
Click the option to PUBLISH when done.
With this rule, authentication is not required to perform read and write actions on your database. This is needful for the application you will be building in this tutorial.
Set Up a Project Using Vue CLI
Vue CLI allows you to scaffold Vue.js projects. If you do not have it on your machine, you can get it by running:
npm install -g vue-cli
This will install it globally on your machine. Here is how Vue-CLI is used.
vue init <template-name> <project-name>
To learn more about Vue-CLI, check the GitHub page.
For this project you will use webpack templates, so run the command below from your terminal.
vue init webpack vue-book
These are the installation options I used.
? Project name vue-book ? Project description A Vue.js project ? Author izuchukwu1 <[email protected]> ? Vue build standalone ? Install vue-router? No ? Use ESLint to lint your code? Yes ? Pick an ESLint preset Standard ? Setup unit tests with Karma + Mocha? No ? Setup e2e tests with Nightwatch? No vue-cli · Generated "vue-book". To get started: cd vue-book npm install npm run dev Documentation can be found at http://ift.tt/28JYKuJ
Navigate to your project folder. The files and folders generated by Vue-CLI have a tree like this.
├── build │ ├── build.js │ ├── check-versions.js │ ├── dev-client.js │ ├── dev-server.js │ ├── utils.js │ ├── vue-loader.conf.js │ ├── webpack.base.conf.js │ ├── webpack.dev.conf.js │ └── webpack.prod.conf.js ├── config │ ├── dev.env.js │ ├── index.js │ └── prod.env.js ├── index.html ├── package.json ├── README.md ├── src │ ├── App.vue │ ├── assets │ │ └── logo.png │ ├── components │ │ └── HelloWorld.vue │ └── main.js └── static 6 directories, 19 files
Now run the command to install your dependencies.
npm install
When done, you can start your dev server by running:
npm run dev
Add Firebase to the Project
To bind Firebase data to Vue.js data properties, we will make use of the VueFire library. You can check more about it on GitHub.
Run the command below:
npm install firebase vuefire --save
Open up main.js to add VueFire. Make your main.js file look like what I have below.
#src/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' import VueFire from 'vuefire' Vue.use(VueFire) Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', template: '<App/>', components: { App } })
Set Up the Firebase Connection
Go to your Firebase console, and click on the Overview link on the left panel. Select the option to add Firebase to your web app. Copy the snippet that pops up in the window to a text file. The snippet contains your apiKey, authDomain, databaseURL, projectId, storageBucket, and messagingSenderId. You need these details to be able to access your Firebase database.
You start by importing Firebase from the core Firebase library. A Firebase instance is created using the initializeApp method. The snippet you copied has to be passed to this method as an object. This has to be done in the script section of your App.vue, like this.
#src/App.vue import Firebase from 'firebase' let config = { apiKey: "...", authDomain: "...", databaseURL: "...", storageBucket: "...", messagingSenderId: "..." }; let app = Firebase.initializeApp(config) let db = app.database() let booksRef = db.ref('books')
After creating the Firebase instance, the database reference is obtained by using app.database().
Book Listing
Since VueFire makes it easy to bind Vue.js data properties to Firebase, implementing the books listing feature requires you to add this.
firebase: { books: booksRef },
You add that below:
name: 'app',
Now you have access to the book items from your database. The template will look like this.
<div class="panel-body"> <table class="table table-striped"> <thead> <tr> <th>Title</th> <th>Author</th> </tr> </thead> <tbody> <tr v-for="book in books"> <td><a v-bind:href="book.url"></a></td> <td></td> </tr> </tbody> </table> </div>
The v-for directive is used to iterate through the available books. Each book will be outputted in a new table row.
Adding a New Book
To put in place the addition of new books, you need to first define the data model that will be used.
data () { return { newBook: { title: '', author: '', url: 'http://', isbn: '' } } }
Next, set up the template to look like this.
<div class="panel panel-default"> <div class="panel-heading"> <h3 class="panel-title">Add New Books</h3> </div> <div class="panel-body"> <form id="form" class="form-inline" v-on:submit.prevent="addBook"> <div class="form-group"> <label for="bookTitle">Title:</label> <input type="text" id="bookTitle" class="form-control" v-model="newBook.title"> </div> <div class="form-group"> <label for="bookAuthor">Author:</label> <input type="text" id="bookAuthor" class="form-control" v-model="newBook.author"> </div> <div class="form-group"> <label for="bookUrl">Url:</label> <input type="text" id="bookUrl" class="form-control" v-model="newBook.url"> </div> <input type="submit" class="btn btn-primary" value="Add Book"> </form> </div> </div>
The v-model directive is used to bind the newBook properties to the corresponding input.
The v-on directive will lead us to create an event handler method that gets called whenever a new book is to be created. Here is what the event handler should look like.
methods: { addBook: function() { booksRef.push(this.newBook) this.newBook.title = '', this.newBook.author = '', this.newBook.url = 'http://', this.newBook.isbn = '' }, },
The addBook method helps insert new book objects into the Firebase database. The data is also synced across all clients.
Deleting Books
Let's add the ability to delete books. Add another column to the book listing.
<td> <span class="glyphicon glyphicon-trash" aria-hidden="true" v-on:click="removeBook(book)"></span> </td>
Let's put in place a method that gets called each time the button is clicked. The method is passed the book you intend to delete, which is actually the key to the book, as you will see soon. The remove() is called on the returned book to delete it from the database.
Here is what the method looks like.
removeBook: function (book) { booksRef.child(book['.key']).remove() }
With that, you are done with App.vue. Putting everything together, here is how your App.vue file should look.
<template> <div id="app" class="container"> <div class="page-header"> <h1>Vue Book</h1> </div> <div class="panel panel-default"> <div class="panel-heading"> <h3>Add Book</h3> </div> <div class="panel-body"> <form id="form" class="form-inline" v-on:submit.prevent="addBook"> <div class="form-group"> <label for="bookTitle">Title:</label> <input type="text" id="bookTitle" class="form-control" v-model="newBook.title"> </div> <div class="form-group"> <label for="bookAuthor">Author:</label> <input type="text" id="bookAuthor" class="form-control" v-model="newBook.author"> </div> <div class="form-group"> <label for="bookUrl">URL:</label> <input type="text" id="bookUrl" class="form-control" v-model="newBook.url"> </div> <div class="form-group"> <label for="bookIsbn">ISBN:</label> <input type="text" id="bookIsbn" class="form-control" v-model="newBook.isbn"> </div> <input type="submit" class="btn btn-primary" value="Add Book"> </form> </div> </div> <div class="panel panel-default"> <div class="panel-heading"> <h3>Books Lists</h3> </div> <div class="panel-body"> <table class="table table-stripped"> <thead> <tr> <th>Title</th> <th>Author</th> <th></th> </tr> </thead> <tbody> <tr v-for="book in books"> <td> <a v-bind:href="book.url"></a> </td> <td> </td> <td> <span class="glyphicon glyphicon-trash" aria-hidden="true" v-on:click="removeBook(book)"></span> </td> </tr> </tbody> </table> </div> </div> </div> </template> <script> import Firebase from 'firebase' let config = { apiKey: "...", authDomain: "...", databaseURL: "...", storageBucket: "...", messagingSenderId: "..." } let app = Firebase.initializeApp(config) let db = app.database() let booksRef = db.ref('books') export default { name: 'app', firebase: { books: booksRef }, data () { return { newBook: { title: '', author: '', url: 'http://', isbn: '' } } }, methods: { addBook: function() { booksRef.push(this.newBook) this.newBook.title = '', this.newBook.author = '', this.newBook.url = 'http://', this.newBook.isbn = '' }, removeBook: function(book) { booksRef.child(book['.key']).remove() } } } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; color: #2c3e50; margin-top: 60px; } </style>
In the template, I added some Bootstrap classes. For these to work, open your index.html file and make it look like this.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>vue-book</title> <link rel="stylesheet" href="http://ift.tt/2apRjw3" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <link rel="stylesheet" href="http://ift.tt/2hbdoRr" /> </head> <body> <div id="app"></div> <!-- built files will be auto injected --> <script src="http://ift.tt/2nfnDrE" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script> <script src="http://ift.tt/2aHTozy" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> </body> </html>
Conclusion
JavaScript has become extremely popular and is now capable of building mature applications (as we've seen above). If you’re looking for additional resources to study or to use in your work, check out what we have available in the Envato Market.
In this tutorial, you learned about Firebase. You were able to connect Vue.js and Firebase using VueFire. Your application can make read and write requests to your Firebase database.
You can go further by adding more features like categories and description.
by Chinedu Izuchukwu via Envato Tuts+ Code http://ift.tt/2zGQubw
3 notes
·
View notes
Text
Building With Vue.js 2 and Firebase
Introduction
Firebase is Google's mobile platform that helps you develop high-quality apps and grow your business. In this tutorial, you will make good use of one of Firebase's awesome features: the Realtime Database.
You will build a single page application to create books. This book will be saved to your Firebase database, and you will be able to retrieve and delete books you have created.
Let's get started.
Set Up Firebase
Go to Google's Firebase page to create a new account. When done with that, log in to your console. Click on the option to add a project. Enter your project details and click on the button CREATE PROJECT.
This will lead you to your console. The Firebase console helps you manage your Firebase configuration settings.
For this tutorial, you'll need to make access to your database public. From the panel on the left, select Database. Select Realtime Database from the options that show next by clicking GET STARTED. Making your database public involves editing the rules. So click RULES on the page that loads next.
Make your rules look like this.
{ "rules": { ".read": true, ".write": true } }
Click the option to PUBLISH when done.
With this rule, authentication is not required to perform read and write actions on your database. This is needful for the application you will be building in this tutorial.
Set Up a Project Using Vue CLI
Vue CLI allows you to scaffold Vue.js projects. If you do not have it on your machine, you can get it by running:
npm install -g vue-cli
This will install it globally on your machine. Here is how Vue-CLI is used.
vue init <template-name> <project-name>
To learn more about Vue-CLI, check the GitHub page.
For this project you will use webpack templates, so run the command below from your terminal.
vue init webpack vue-book
These are the installation options I used.
? Project name vue-book ? Project description A Vue.js project ? Author izuchukwu1 <[email protected]> ? Vue build standalone ? Install vue-router? No ? Use ESLint to lint your code? Yes ? Pick an ESLint preset Standard ? Setup unit tests with Karma + Mocha? No ? Setup e2e tests with Nightwatch? No vue-cli · Generated "vue-book". To get started: cd vue-book npm install npm run dev Documentation can be found at http://ift.tt/28JYKuJ
Navigate to your project folder. The files and folders generated by Vue-CLI have a tree like this.
├── build │ ├── build.js │ ├── check-versions.js │ ├── dev-client.js │ ├── dev-server.js │ ├── utils.js │ ├── vue-loader.conf.js │ ├── webpack.base.conf.js │ ├── webpack.dev.conf.js │ └── webpack.prod.conf.js ├── config │ ├── dev.env.js │ ├── index.js │ └── prod.env.js ├── index.html ├── package.json ├── README.md ├── src │ ├── App.vue │ ├── assets │ │ └── logo.png │ ├── components │ │ └── HelloWorld.vue │ └── main.js └── static 6 directories, 19 files
Now run the command to install your dependencies.
npm install
When done, you can start your dev server by running:
npm run dev
Add Firebase to the Project
To bind Firebase data to Vue.js data properties, we will make use of the VueFire library. You can check more about it on GitHub.
Run the command below:
npm install firebase vuefire --save
Open up main.js to add VueFire. Make your main.js file look like what I have below.
#src/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' import VueFire from 'vuefire' Vue.use(VueFire) Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', template: '<App/>', components: { App } })
Set Up the Firebase Connection
Go to your Firebase console, and click on the Overview link on the left panel. Select the option to add Firebase to your web app. Copy the snippet that pops up in the window to a text file. The snippet contains your apiKey, authDomain, databaseURL, projectId, storageBucket, and messagingSenderId. You need these details to be able to access your Firebase database.
You start by importing Firebase from the core Firebase library. A Firebase instance is created using the initializeApp method. The snippet you copied has to be passed to this method as an object. This has to be done in the script section of your App.vue, like this.
#src/App.vue import Firebase from 'firebase' let config = { apiKey: "...", authDomain: "...", databaseURL: "...", storageBucket: "...", messagingSenderId: "..." }; let app = Firebase.initializeApp(config) let db = app.database() let booksRef = db.ref('books')
After creating the Firebase instance, the database reference is obtained by using app.database().
Book Listing
Since VueFire makes it easy to bind Vue.js data properties to Firebase, implementing the books listing feature requires you to add this.
firebase: { books: booksRef },
You add that below:
name: 'app',
Now you have access to the book items from your database. The template will look like this.
<div class="panel-body"> <table class="table table-striped"> <thead> <tr> <th>Title</th> <th>Author</th> </tr> </thead> <tbody> <tr v-for="book in books"> <td><a v-bind:href="book.url"></a></td> <td></td> </tr> </tbody> </table> </div>
The v-for directive is used to iterate through the available books. Each book will be outputted in a new table row.
Adding a New Book
To put in place the addition of new books, you need to first define the data model that will be used.
data () { return { newBook: { title: '', author: '', url: 'http://', isbn: '' } } }
Next, set up the template to look like this.
<div class="panel panel-default"> <div class="panel-heading"> <h3 class="panel-title">Add New Books</h3> </div> <div class="panel-body"> <form id="form" class="form-inline" v-on:submit.prevent="addBook"> <div class="form-group"> <label for="bookTitle">Title:</label> <input type="text" id="bookTitle" class="form-control" v-model="newBook.title"> </div> <div class="form-group"> <label for="bookAuthor">Author:</label> <input type="text" id="bookAuthor" class="form-control" v-model="newBook.author"> </div> <div class="form-group"> <label for="bookUrl">Url:</label> <input type="text" id="bookUrl" class="form-control" v-model="newBook.url"> </div> <input type="submit" class="btn btn-primary" value="Add Book"> </form> </div> </div>
The v-model directive is used to bind the newBook properties to the corresponding input.
The v-on directive will lead us to create an event handler method that gets called whenever a new book is to be created. Here is what the event handler should look like.
methods: { addBook: function() { booksRef.push(this.newBook) this.newBook.title = '', this.newBook.author = '', this.newBook.url = 'http://', this.newBook.isbn = '' }, },
The addBook method helps insert new book objects into the Firebase database. The data is also synced across all clients.
Deleting Books
Let's add the ability to delete books. Add another column to the book listing.
<td> <span class="glyphicon glyphicon-trash" aria-hidden="true" v-on:click="removeBook(book)"></span> </td>
Let's put in place a method that gets called each time the button is clicked. The method is passed the book you intend to delete, which is actually the key to the book, as you will see soon. The remove() is called on the returned book to delete it from the database.
Here is what the method looks like.
removeBook: function (book) { booksRef.child(book['.key']).remove() }
With that, you are done with App.vue. Putting everything together, here is how your App.vue file should look.
<template> <div id="app" class="container"> <div class="page-header"> <h1>Vue Book</h1> </div> <div class="panel panel-default"> <div class="panel-heading"> <h3>Add Book</h3> </div> <div class="panel-body"> <form id="form" class="form-inline" v-on:submit.prevent="addBook"> <div class="form-group"> <label for="bookTitle">Title:</label> <input type="text" id="bookTitle" class="form-control" v-model="newBook.title"> </div> <div class="form-group"> <label for="bookAuthor">Author:</label> <input type="text" id="bookAuthor" class="form-control" v-model="newBook.author"> </div> <div class="form-group"> <label for="bookUrl">URL:</label> <input type="text" id="bookUrl" class="form-control" v-model="newBook.url"> </div> <div class="form-group"> <label for="bookIsbn">ISBN:</label> <input type="text" id="bookIsbn" class="form-control" v-model="newBook.isbn"> </div> <input type="submit" class="btn btn-primary" value="Add Book"> </form> </div> </div> <div class="panel panel-default"> <div class="panel-heading"> <h3>Books Lists</h3> </div> <div class="panel-body"> <table class="table table-stripped"> <thead> <tr> <th>Title</th> <th>Author</th> <th></th> </tr> </thead> <tbody> <tr v-for="book in books"> <td> <a v-bind:href="book.url"></a> </td> <td> </td> <td> <span class="glyphicon glyphicon-trash" aria-hidden="true" v-on:click="removeBook(book)"></span> </td> </tr> </tbody> </table> </div> </div> </div> </template> <script> import Firebase from 'firebase' let config = { apiKey: "...", authDomain: "...", databaseURL: "...", storageBucket: "...", messagingSenderId: "..." } let app = Firebase.initializeApp(config) let db = app.database() let booksRef = db.ref('books') export default { name: 'app', firebase: { books: booksRef }, data () { return { newBook: { title: '', author: '', url: 'http://', isbn: '' } } }, methods: { addBook: function() { booksRef.push(this.newBook) this.newBook.title = '', this.newBook.author = '', this.newBook.url = 'http://', this.newBook.isbn = '' }, removeBook: function(book) { booksRef.child(book['.key']).remove() } } } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; color: #2c3e50; margin-top: 60px; } </style>
In the template, I added some Bootstrap classes. For these to work, open your index.html file and make it look like this.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>vue-book</title> <link rel="stylesheet" href="http://ift.tt/2bUjS7M; integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <link rel="stylesheet" href="http://ift.tt/2iB9WD6; /> </head> <body> <div id="app"></div> <!-- built files will be auto injected --> <script src="http://ift.tt/2qsg3fq; integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script> <script src="http://ift.tt/2c7Wssx; integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> </body> </html>
Conclusion
JavaScript has become extremely popular and is now capable of building mature applications (as we've seen above). If you’re looking for additional resources to study or to use in your work, check out what we have available in the Envato Market.
In this tutorial, you learned about Firebase. You were able to connect Vue.js and Firebase using VueFire. Your application can make read and write requests to your Firebase database.
You can go further by adding more features like categories and description.
via Envato Tuts+ Code http://ift.tt/2gDufeR
0 notes
Text
VueJS & Firebase Cloud Firestore Stripped-Back - Tutorial Part 3
In this tutorial series we are using a stripped-back approach to getting started with Vuejs & Firebase Cloud Firestore to build full-stack web applications. No CLIs or build tools, just a HTML page.
Retrieving realtime data
In part three of this tutorial we’re covering the R in CRUD, reading or retrieving data. We’ll cover querying the employee data we want, retrieve and display it in our app page and make it all work in realtime. If you haven’t read the previous part of the tutorial you can get it here, if you haven’t read the first part you can do so here. In the previous part we covered creating employee records and in this part we want to display those records in our app so you can see instantly when a new record has been added. We want to get the data back at the very beginning of our app so the list of existing employees displays immediately. To achieve this we’ll need to add the code to retrieve the data into the created lifecycle hook. We then declare a query based on the collection we want to retrieve from eg Employees
created : function() { let that = this that.db = firebase.firestore()
let query = that.db.collection(’Employees’)
}
Note : We covered the issue of using this in part 2. We resolved it in our functions inside of the methods object by using arrow functions rather than standard functions and referencing the Instance Object explicitly eg app. However as Vue recommends not to use arrow functions for lifecycle hooks like created, I’ve opted for consistency by assigning this to a variable called that and refering to that throughout the lifecycle hook function when referencing the properties and methods of the Vue Instance. Now we have a Firestore query object assigned which points to the collection we want, we can call a method on that object to actually retrieve the data from Firestore. There are a couple of methods we can use to grab the data back from the query but we want to get it in realtime. When we say realtime we essentially want to retrieve the data from the query immediately and then listen for any changes in the data which occur so we can act on those changes as they happen. So once we retrieve data in realtime we can react to changes in the same way as you would upon initially retrieving it - to display them on our page using Vue’s directives and data binding. The next thing we need to do is to a declare a new array in the data section of our Instance Object that we can retrieve the employee data into and display on the page.
var app = new Vue({ el : ’#app’, data : { appTitle : ‘EmployeeMagic’, mainStyle : { ‘margin’ : ’20px’ }, employee : {firstName : ‘’, lastName : ‘’, jobTitle : ‘’, dept : ‘’, age : 0 }, db : {}, employees : [ ] },
Now we have our employees array, we can go back to our created function and run our query using Firestore’s onSnapshot() method. onSnapshot() expects a function that will be triggered initially and then whenever the data changes. This is what is termed a callback function. onSnapshot() is unusual amongst Firestore methods as it uses a callback rather than returning a promise to handle asynchronous calls to the database and it’s important to note the difference. If we had used an alternative method to onSnapshot() to retrieve the data, such as get(), it would return a promise instead (as we covered in part 2) however in that circumstance the code you implemented to manage the data retrieval would only ever be called once which is easier to manage with a promise rather than, in this case, potentially being run multiple times whenever any data changes occur. The function we pass to onSnapshot() receives a snapshot parameter which is an object containing the actual data that comes back from Firestore in response to our query.
created : function() { let that = this that.db = firebase.firestore() let query = that.db.collection(’Employees’) query.onSnapshot((snapshot) => {
}) }
In our callback function, we pick up the snapshot and manipulate it to retrieve the data into our employees array. Remembering that this function will be run each time data is changed on our queried data, not just the first time it’s run, we need to empty our employees array so we don’t end up displaying duplicate data.
Our next step is to use a method that’s included as part of the snapshot object, forEach(). The forEach() method receives another callback function that it runs for each employee as it iterates over every retrieved document in the snapshot. In the callback function that we pass in, we tell it what is to happen for each employee, in our case we want it to add each document to our employees array. Our forEach callback function receives a parameter which is the document or employee for the current iteration, in our example we call it doc. We can then use doc to extract the fields from the current document and into our array using the array’s push() method.
query.onSnapshot((snapshot) => { that.employees = [ ] snapshot.forEach((doc) => { that.employees.push({ firstName : doc.data().firstName, lastName : doc.data().lastName, jobTitle : doc.data().jobTitle, dept : doc.data().dept, age : doc.data().age }) })
})
To get the actual field information out of each document we have to call it’s data() method first followed by the field name we want. So far so good. We’ve got our data out of our Firestore and into an array we can use on the page and we’ve got a change listener so whenever any data is added, changed or deleted we know the list will be refreshed in realtime. Our next task is to use Vue to display the data on the page.
We’re going to add a table to our page which we’ll style a little bit with Bootstrap and we’ll add a new style to Vue, as we covered in part 1, to put a margin at the top of the table.
var app = new Vue({ el : ’#app’, data : { appTitle : ‘EmployeeMagic’, mainStyle : { ‘margin’ : ’20px’ }, tableStyle : {’margin-top’ : ‘20px’}, employee : {firstName : ‘’, lastName : ‘’, jobTitle : ‘’, dept : ‘’, age : 0 }, db : {}, employees : [ ] },
In the template we’ll apply our style and insert a table with the column headers. Note we’re including one column to display the full name rather than separate columns for the first and last names.
<div :style="tableStyle"> <table class="table table-bordered table-striped"> <thead> <th>Name</th> <th>Job Title</th> <th>Department</th> <th>Age</th> </thead> </table> </div>
Our next step is to display the actual data. Like most frameworks, Vue has a mechanism to iterate through arrays and repeat part of a template based on the elements in the array. In Vue this is the v-for directive and we’ll use it to repeat a <tr> tag for each employee in our employees array that is populated with data we retrieved from Firestore.
</thead> <tbody> <tr v-for=“employee in employees”>
Next we’ll add in the columns of information and to display the information from our array, we reference employee (as defined in our v-for directive) and the property name using data binding with curly braces.
<td>{{ employee.firstName }} {{ employee.lastName }}</td> <td>{{ employee.jobTitle }}</td> <td>{{ employee.dept }}</td> <td>{{ employee.age }}</td> </tr> </tbody> </table> </div>
If you now save and refresh you should now see the employee records you entered so far displayed when your app runs. Just to ensure your realtime updates are working, add a new employee record and click Save and your list will automatically refresh to include the new record. Pretty cool.
We’ve almost done with the R part of CRUD but we’ll just cover one more thing before you go and make yourself a cuppa tea. You might notice that the data isn’t sorted in any particular order and it’s a bit untidy. Ideally we would like to sort the data by name, specifically the employee’s last name. This is really easy to do with Firestore. In the created hook function, go to the line where you declare the query object. At the moment we’re just referencing the Employees collection, we’re not filtering the list with a query and we’re not sorting on it, we’re just getting everything in any order Firestore feels like sending it to us. To sort this query by the employee’s last name all we need to do is add a call to the orderBy() method and pass in the field name you want to sort by.
created : function() { let that = this that.db = firebase.firestore() let query = that.db.collection(’Employees’).orderBy(’lastName’) query.onSnapshot((snapshot) => {
Save your file and refresh your browser and you’ll notice your list of employees is now sorted by the employee’s last names. Easy eh? In a future part of this tutorial we’ll cover more about sorting data and also querying to retrieve filtered data.
In this part of the tutorial we’ve covered how to setup a query to retrieve a collection from Firestore and how to retrieve updates to the collection in realtime. We’ve covered callbacks to trigger code whenever changes are made and how to populate an array in our Vue object from data in a Firestore collection and then use a table to display that data using Vue’s v-for directive and data binding and finally how to sort the data coming from Firestore. In the fourth part of this tutorial we’ll continue with CRUD, addressing the U for updating where we’ll cover how to edit and update an employee. Look forward to your company :)
You can download the completed code for this part of the tutorial on Github using the repo below and select the part3 folder. https://github.com/MancDev/VueFire
0 notes