So lets get started.
Firebase:
- Firebase is a real-time database service, i.e your modification are updated in real time and you don’t need to refresh a page, to see the changes.
- Firebase uses NoSQL. So leave aside some of the old school SQL concepts.
- Firebase is not suitable for all occasions. Here I have used it basically for the reason that, I need a Real time Cart and a Real time Order Tracking.
Index:
index.html [The container]
This is the main container that holds Sliding Drawer and Navigation Bar. We need to hide some of this segments before login. You can find the respective sections in the below code.#1. The custom headers for Ionic Material and Firebase
#2. To obtain your Firebase configuration part follow this.
#3. $root.extras is used for hiding user features, ie cart icon, menu drawer, navigation icon etc.
We initialize $root.extras to false in the app.js
.run(function($ionicPlatform,$rootScope) { $rootScope.extras = false; $ionicPlatform.ready(function() {
#4.get_total() returns the total number of cart items.
#5.In-order to access $root.extras and get_total(), we have added an additional controller i.e indexCtrl. Currently we wont be looking into it, as it will only come after login.
Menu Offers My Cart Orders Favourite Settings Support Logout
Login:
login.html [The login page]
Find following sections in the below code
#1. style attribute for adding full screen background
#2. Will be implementing FB login in a while.
FORGOT PASSWORD
controllers.js [ loginCtrl ]
/* ionicSideMenuDelegate : used to access the slidable functionality of the menu drawer */ .controller('loginCtrl', function($scope,$rootScope,$ionicHistory,sharedUtils,$state,$ionicSideMenuDelegate) { $rootScope.extras = false; // For hiding the side bar and nav icon // When the user logs out and reaches login page, // we clear all the history and cache to prevent back link $scope.$on('$ionicView.enter', function(ev) { if(ev.targetScope !== $scope){ $ionicHistory.clearHistory(); $ionicHistory.clearCache(); } }); //Check if user already logged in firebase.auth().onAuthStateChanged(function(user) { if (user) { //Removes back link to login page $ionicHistory.nextViewOptions({ historyRoot: true }); $ionicSideMenuDelegate.canDragContent(true); // Sets up the sideMenu dragable $rootScope.extras = true; sharedUtils.hideLoading(); $state.go('menu2', {}, {location: "replace"}); } }); $scope.loginEmail = function(formName,cred) { if(formName.$valid) { // Check if the form data is valid or not sharedUtils.showLoading(); //starts the loading popup //Email Login via Firebase firebase.auth().signInWithEmailAndPassword(cred.email,cred.password).then(function(result) { // You dont need to save the users session in your local session or cookies. Firebase handles it. // You only need to : // 1. clear the login page history from the history stack so that you cant come back // 2. Set rootScope.extra; // 3. Turn off the loading // 4. Got to menu page $ionicHistory.nextViewOptions({ historyRoot: true //1 }); $rootScope.extras = true; //2 sharedUtils.hideLoading(); //3 $state.go('menu2', {}, {location: "replace"}); //4 }, function(error) { sharedUtils.hideLoading(); sharedUtils.showAlert("Please note","Authentication Error"); } ); }else{ sharedUtils.showAlert("Please note","Entered data is not valid"); } }; $scope.loginFb = function(){ //Facebook Login }; $scope.loginGmail = function(){ //Gmail Login }; })
services.js [ sharedUtils and fireBaseData ]
sharedUtils : Contains commonly used functions like show_loading_popup, show_alert etc.
fireBaseDate : Contains the Reference URL of all the tables in your firebase database.
.factory('fireBaseData', function($firebase) { var ref = new Firebase("https://projectId.firebaseio.com/"), refCart = new Firebase("https://projectId.firebaseio.com/cart"), refUser = new Firebase("https://projectId.firebaseio.com/users"), refCategory = new Firebase("https://projectId.firebaseio.com/category"), refOrder = new Firebase("https://projectId.firebaseio.com/orders"), refFeatured = new Firebase("https://projectId.firebaseio.com/featured"), refMenu = new Firebase("https://projectId.firebaseio.com/menu"); return { ref: function() { return ref; }, refCart: function() { return refCart; }, refUser: function() { return refUser; }, refCategory: function() { return refCategory; }, refOrder: function() { return refOrder; }, refFeatured: function() { return refFeatured; }, refMenu: function() { return refMenu; } } }) .factory('sharedUtils',['$ionicLoading','$ionicPopup', function($ionicLoading,$ionicPopup){ var functionObj={}; functionObj.showLoading=function(){ $ionicLoading.show({ content: ' ', // The text to display in the loading indicator animation: 'fade-in', // The animation to use showBackdrop: true, // Will a dark overlay or backdrop cover the entire view maxWidth: 200, // The maximum width of the loading indicator. Text will be wrapped if longer than maxWidth showDelay: 0 // The delay in showing the indicator }); }; functionObj.hideLoading=function(){ $ionicLoading.hide(); }; functionObj.showAlert = function(title,message) { var alertPopup = $ionicPopup.alert({ title: title, template: message }); }; return functionObj; }])
Register :
signup.html [The Signup page]
controllers.js [The Signup page]
.controller('signupCtrl', function($scope,$rootScope,sharedUtils,$ionicSideMenuDelegate, $state,fireBaseData,$ionicHistory) { $rootScope.extras = false; // For hiding the side bar and nav icon $scope.signupEmail = function (formName, cred) { if (formName.$valid) { // Check if the form data is valid or not sharedUtils.showLoading(); //Main Firebase Authentication part firebase.auth().createUserWithEmailAndPassword(cred.email, cred.password).then(function (result) { //Add name and default dp to the Autherisation table result.updateProfile({ displayName: cred.name, photoURL: "default_dp" }).then(function() {}, function(error) {}); //We create a user table to store users additional information.Here, telephone //Add phone number to the user table fireBaseData.refUser().child(result.uid).set({ telephone: cred.phone }); //Registered OK $ionicHistory.nextViewOptions({ historyRoot: true }); $ionicSideMenuDelegate.canDragContent(true); // Sets up the sideMenu dragable $rootScope.extras = true; sharedUtils.hideLoading(); $state.go('menu2', {}, {location: "replace"}); }, function (error) { sharedUtils.hideLoading(); sharedUtils.showAlert("Please note","Sign up Error"); }); }else{ sharedUtils.showAlert("Please note","Entered data is not valid"); } } })
Profile :
settings.html [The Profile Page]
controllers.js [ settingsCtrl ]
/* firebaseArray: for accessing synchronized array of objects firebaseObject: for accessing single synchronized object */ .controller('settingsCtrl', function($scope,$rootScope,fireBaseData,$firebaseObject, $ionicPopup,$state,$window,$firebaseArray, sharedUtils) { //Bugs are most prevailing here $rootScope.extras=true; //Shows loading bar sharedUtils.showLoading(); //Check if user already logged in firebase.auth().onAuthStateChanged(function(user) { if (user) { //Accessing an array of objects using firebaseObject, does not give you the $id , so use firebase array to get $id $scope.addresses= $firebaseArray(fireBaseData.refUser().child(user.uid).child("address")); // firebaseObject is good for accessing single objects for eg:- telephone. Don't use it for array of objects $scope.user_extras= $firebaseObject(fireBaseData.refUser().child(user.uid)); $scope.user_info=user; //Saves data to user_info //NOTE: $scope.user_info is not writable ie you can't use it inside ng-model of //You have to create a local variable for storing emails $scope.data_editable={}; $scope.data_editable.email=$scope.user_info.email; // For editing store it in local variable $scope.data_editable.password=""; $scope.$apply(); sharedUtils.hideLoading(); } }); //Function 1 $scope.addManipulation = function(edit_val) { // Takes care of address add and edit ie Address Manipulator if(edit_val!=null) { $scope.data = edit_val; // For editing address var title="Edit Address"; var sub_title="Edit your address"; } else { $scope.data = {}; // For adding new address var title="Add Address"; var sub_title="Add your new address"; } // An elaborate, custom popup var addressPopup = $ionicPopup.show({ template: ' ' + ' ' + ' ' + '', title: title, subTitle: sub_title, scope: $scope, buttons: [ { text: 'Close' }, { text: 'Save', type: 'button-positive', onTap: function(e) { if (!$scope.data.nickname || !$scope.data.address || !$scope.data.pin || !$scope.data.phone ) { e.preventDefault(); //don't allow the user to submit unless he enters full details } else { return $scope.data; } } } ] }); addressPopup.then(function(res) { if(edit_val!=null) { //Update address fireBaseData.refUser().child($scope.user_info.uid).child("address").child(edit_val.$id).update({ // update nickname: res.nickname, address: res.address, pin: res.pin, phone: res.phone }); }else{ //Add new address fireBaseData.refUser().child($scope.user_info.uid).child("address").push({ // push nickname: res.nickname, address: res.address, pin: res.pin, phone: res.phone }); } }); }; // A confirm dialog for deleting address $scope.deleteAddress = function(del_id) { var confirmPopup = $ionicPopup.confirm({ title: 'Delete Address', template: 'Are you sure you want to delete this address', buttons: [ { text: 'No' , type: 'button-stable' }, { text: 'Yes', type: 'button-assertive' , onTap: function(){return del_id;} } ] }); confirmPopup.then(function(res) { if(res) { fireBaseData.refUser().child($scope.user_info.uid).child("address").child(res).remove(); } }); }; //Function 2 $scope.save= function (extras,editable) { //1. Edit Telephone doesnt show popup 2. Using extras and editable // Bugs if(extras.telephone!="" && extras.telephone!=null ){ //Update Telephone fireBaseData.refUser().child($scope.user_info.uid).update({ // set telephone: extras.telephone }); } //Edit Password if(editable.password!="" && editable.password!=null ){ //Update Password in UserAuthentication Table firebase.auth().currentUser.updatePassword(editable.password).then(function(ok) {}, function(error) {}); sharedUtils.showAlert("Account","Password Updated"); } //Edit Email if(editable.email!="" && editable.email!=null && editable.email!=$scope.user_info.email){ //Update Email/Username in UserAuthentication Table firebase.auth().currentUser.updateEmail(editable.email).then(function(ok) { $window.location.reload(true); //sharedUtils.showAlert("Account","Email Updated"); }, function(error) { sharedUtils.showAlert("ERROR",error); }); } }; $scope.cancel=function(){ // Simple Reload $window.location.reload(true); console.log("CANCEL"); } })
Its almost done. Now you only need to configure some database elements.
CONFIGURE DATABASE:
1. Open up your project db.
2. Import the following JSON data to the Foodkart db
{ "category" : { "cat01" : "Burger", "cat02" : "Drinks" }, "featured" : { "item1" : "slide_1", "item2" : "slide_2" }, "menu" : { "item1" : { "available" : true, "category" : "cat01", "description" : "item1 description", "image" : "chicken_maharaja", "name" : "New Chicken Maharaja", "price" : 130, "stock" : 100 }, "item2" : { "available" : true, "category" : "cat01", "description" : "item2 description", "image" : "big_spicy_chicken_wrap", "name" : "Big Spicy Chicken Wrap", "price" : 120, "stock" : 100 }, "item3" : { "available" : true, "category" : "cat02", "description" : "item3 description", "image" : "thumsup", "name" : "Thumsup 100ml", "price" : 40, "stock" : 100 }, "item4" : { "available" : true, "category" : "cat02", "description" : "item4 description", "image" : "mccafe_ice_coffee", "name" : "Ice Coffee", "price" : 140, "stock" : 100 }, "item5" : { "available" : true, "category" : "cat01", "description" : "item5 description", "image" : "mc_chicken", "name" : "MC Chicken", "price" : 190, "stock" : 100 }, "item6" : { "available" : true, "category" : "cat02", "description" : "item6 description", "image" : "Smoothie", "name" : "Smoothie", "price" : 70, "stock" : 100 }, "item8" : { "available" : true, "category" : "cat01", "description" : "item8 description", "image" : "salad_wrap", "name" : "Salad Wrap", "price" : 150, "stock" : 100 } } }
Note: Rest of the databases are automatically created, when making the database calls.
3. Add the following permissions to the database rules .
{ "rules": { ".read": true, ".write": true }Note: When you are publishing the app, make sure to update these permissions to a more constrained version. This concludes the part for Login, Register and Profile Setting for FoodKart using Firebase.
0 komentar:
Posting Komentar
Terimakasih Sudah Berkomentar dengan Sopan