Flutter App with Firebase Authentication and Firestore Tutorial - Crypto Wallet

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi everyone i'm beau i run the blyle dev channel on youtube and today we're going to be going over how to create a full stack flutter application utilizing firebase authentication and firebase firestore along with some open sourced apis for this project we're going to have four key parts that we're going to be setting up firebase setup flutter setup to integrate with firebase we're going to build our flutter application and last we're going to hook up our apis to our application as well as firestore to our application by the end of this video you should be able to hook up apis into your flutter application and utilize them you should be able to utilize firebase authentication in your app at a more basic level and we should be able to perform crud operations using firestore in your flutter application so those are the main goals that we're going to focus on today to accomplish these goals we're going to be building a cryptocurrency wallet app we're going to be able to add coins and how much of that coin a user has to the wallet we're going to be able to read the current value converted into u.s dollars of that wallet and we're going to allow the users to sell or remove coins from their wallet and this basic functionality is going to allow us to practice using our apis using firestore and using firebase authentication i'd like to thank free code camp for this awesome opportunity make sure to subscribe to their channel below by clicking that subscribe button and if you're interested there'll be a link to my channel in the description as well for this project we're going to be using vs code as our main editor i'm going to assume that you've probably already done a flutter application or two before this video if you haven't that's okay you can follow along and build this out as we go if you're new to flutter development that's okay be sure to check out flutter.dev and then follow their steps for setting up your machine to use flutter in this case we're going to be using vs code and utilizing some of their flutter extensions in our project the key one being awesome flutter flutter and dart language support the first thing we need to do is set up firebase to work with our application but before we can do that we need to create a project first so that we can hook it up to firebase to do this we're going to open up our command prompt in vs code and we're going to select flutter new project for this project we're going to call it crypto wallet and then i'm just going to place it on my desktop once your app's finished building we're going to go over to firebase and you're going to go to firebase.google.com and we're going to click get started and all we're going to do is follow the prompts for creating a new project so i'm going to call my crypto wallet i'm going to enable google analytics select my default analytics account once it's finished building you'll get a page like this and we'll click continue this is your firebase dashboard this is where we're going to manage everything that we're going to be using with firebase from authentication to our firestore hookups and to setting up the connections to our mobile app the first thing we want to do is we want to configure firebase to connect to our flutter application to do this we're going to click on ios there's one field that we need to incorporate in order to hook up our ios side of our app to firebase and that's our bundle identifier to find your bundle identifier you're going to go into your flutter application in xcode if you're developing on a mac you want to make sure you open up xcode we're going to go to our ios folder and we're going to select the white icon runner.xc workspace not work proj i'm going to open it i'm going to click on our runner and under general you're going to see here we have our bundle identifier and we're simply going to copy this and paste it into google alternatively another way to find your bundle identifier is by opening up the ios folder runner.xcodeproject project.pbxproj and then you're going to search for bundle and you're going to see here there's a variable called product bundle identifier and that is the name of the bundle id that you want to use so if you're not using mac or alternatively you just don't want to open xcode you can go to this file and grab the product bundle identifier and use that instead we're going to select register app we're going to download the config file i'm just going to drag it to my desktop next we can skip this step we can skip this step as that is specific to swift and we can skip the verify the next piece we want to do is we want to make sure we add the android side to our app now this is going to be similar but the package name is going to be slightly different so you'll see here they suggest you go to your app level android app build.gradle and right near the top you'll see under default config and application id and this is going to be our package name i'm going to copy that we're going to paste it here register that app download the config file and unlike the ios side we are going to follow the instructions listed in the following extra tasks so the first one it tells us to do is go to our project folders build.gradle file and we are going to add in the following line when it means project level it means the android root folder and we're simply going to add this right here in our dependencies under our build script the next thing we're going to do is we're going to navigate to our app build.gradle and we're going to copy the supply plug-in line and paste it right here with the other apply plug-ins and then we're going to get under dependency we're going to add firebase analytics because we've got that enabled there we go everything's set up for android skip that step and the last thing we want to do is in our project we want to make sure we add in our new google files that we downloaded our config files our one for ios and our one for android for ios what we're going to do is you're going to navigate to your runner folder the same folder where you find your info.plist and that's where we're going to place our file quick side note if you're building on ios and run into an issue where it can't find the google plist file that we recently downloaded from firebase don't worry there's a quick fix to it go into xcode right click on runner click add files to runner and then you're going to want to select the google service info p list that we recently downloaded add it there you go and now you shouldn't get this issue anymore the android google file should be placed right within this app folder okay we have two more very simple steps to follow to finish our firebase setup the first that we want to do is we want to set up authentication for this application we're going to set up a sign in method of email and password and we're just going to check the top box and that's it now we can hook up our app to firebase authentication the next thing we want to do is we want to go to cloud firestore click create database and we're going to start it in test mode what test mode is it's going to allow any read and write abilities to this database but it's going to place a time stamp on it we're going to use this for our testing and once we're ready to deploy into production we're going to change it to production mode and modify the rules next we're going to select a region since i'm on the east coast of the us but i anticipate a lot of west coast users as that's where a lot of family and friends are i'm going to keep it on uscentral and there we have it we've officially set up our firebase console to manage our flutter application the next thing we're going to do is i'm going to quickly clean up the flutter application in our main.dart file i'm going to remove the theme.date the theme data i'm going to simplify this class below the homepage class remove a title from its implementation and then i'm going to clear out most of the contents of the clear state class i'm going to clear out everything within scaffold and only have a body of type container remove this title okay and i'm going to remove this unused method okay i'm officially ready to start my flutter application but the first thing we're going to do is we're going to install the packages necessary to talk with firebase from our flutter application so let's go ahead and do that next the first thing we need to do is we need to go to our pubspec.yaml file and underneath of dependencies this is where we're going to put our flutter fire dependencies the first dependency we want to add is authentication so we're just going to copy straight from the firebase.flutter.dev documentation and we're going to paste it into our app and this will give us the most recent version available on firefighter next up we're going to go down to cloud firestore and do the same thing except we don't need to copy in firebase core as we already did that with authentication okay upon saving vs code should run pubget if not you need to open up your terminal and run flutter pub get that way it imports it into your application and that's it that was the most difficult part about connecting with firebase everything from here on out is going to be a breeze so with that let's go ahead and build out our flutter application the first thing i'm going to do is i'm going to shell out all the files that i know i'm going to need in anticipation of having to create them anyways so let's go ahead and do that i'm going to create a couple folders one called model one that i'm going to call net and the other that i'm going to call ui and i'm going to go ahead and create a file called authentication and what we're going to do here is we're going to have a single file that handles our authentication there'll be two fields there'll be an email field a password field and we'll have both a login and register button so regardless of what the user is intending to do whether sign up or sign in they can do it all from that same page the next two files i know i'm going to need are my flutter fire functions file and my api functions file so i'm going to go ahead and create those in my net folder and lastly i'm going to have one model class at least which is going to contain my coin class for the time being we're only going to mess with our authentication file and we'll come back to these other ones later on we're going to first import material [Applause] and then we're going to create a stateful widget and that's going to be called authentication with a capital a it's important to note that file names are always lowercase letters with underscores in between words and your classes are always uppercase camel case so the first letter in each new word is uppercase and the rest are lower i'm then going to add just a simple container and i'm going to make the container a material okay the next thing i'm going to do is i'm actually going to delete the class from the main file i should have just done that to begin with and instead of my home page being the file that we're going to return we're going to return authentication one more thing that we want to make sure that we incorporate into our application is instantializing our firebase hookup so right at the very start we're going to call await firebase.initialize app and we're going to do this right inside our main we're going to then import firebase core make this main method asynchronous and we're off to the races so we're first going to focus all on the ui of our authentication page so let's go ahead and do that the first thing we want to do is we want to give our container a width of media query dot size dot width and we're going to give it a height of media queried out of context not size to height what this will do is it'll expand the container to fill the screen's max width and max height so it'll fill the entire screen we're then going to add a decoration of type box decoration and this is going to allow us to modify the colors if you want to add bordering to any containers if you want to add any additional styling you'll always use a decoration to do this so i'm going to say colors dot let's do a blue accent for now add a comma for some there we go and we're going to add a child of type text that's just going to say hello world the last thing we're going to do before we start up this app is we are going to add widgetsflutterbinding.ensure initialize this is a method we need to add if we're going to initialize the application in our main method now that all the setup is done we're going to go back to our authentication file and we're going to get to work on our authentication page so the first thing we're going to do is we're going to make this a scaffold that it's going to be returning which takes a type body so we had it as material that was the default that the class builder object created but we want it to be of type scaffold for this root container and then instead of hello world we are going to have a column and the reason for this is we want to display two fields an email form field a password form field and then we want to have two buttons and they're all vertical so there's nothing to the left or right it's just up and down and so a column is going to allow us to place all of those vertically positioned from each other so the first one we have is a text form field and this is going to be for our email we're going to have another text form field for our password we are going to have a let's just do it inside of a container for our buttons okay and we're going to start filling these out so what we need to do is since we're doing a text form field we need to have a controller that can capture the input that the user puts into the form so to do this we need a text editing controller and we're going to call this one email field and it's going to be equal to a text editing controller and then we're going to repeat the same thing for password we're just going to call it password instead of email field so password field and these are going to be the values that we're going to pass to our method when the user clicks login or register the next thing we're going to do is we're going to add these controllers to our text form fields that we just created so for the top one it's the email controller and for the bottom one it's the password the next thing we want to do is we want to make sure the user feels secure when they're entering their password so we don't want to just show the password for anyone to see we just want them to be able to see it one letter at a time and so what we're going to do for that is there's a method here called obscure text it's a it's a property on text form field and it takes in a boolean input so by simply saying true what will happen is when the user's typing in it'll block out all the previously typed characters so that's the kind of action that we want to have and then the last thing we want to do is we want to give these a decoration so i believe text input decoration no input decorate that's the one input decoration and you can see even i struggle with this having done it hundreds of times don't feel bad if you have to google something or if you have to mess around with it a little bit in order to find the field that you're really looking for so for input decoration this is going to allow us to change things such as the hint or the label associated with the feel styling for the input input text form field um it's gonna allow us to manipulate all of these different things so what we're gonna do is we're gonna put a hint text and it'll be something uh let's just say email.com the next thing that we want to change is we want to add a label for label text we'll just call it email and for label style it takes in a text style input and we're going to say colors dot white okay and we're going to do the same thing for hint style we're going to say text style color it's colors dot white okay and by putting a trailing comma like this the dart formatter will format our code for us and i think that's all we want to do for this one so what we're going to do is we're going to actually copy this decoration we're going to come down to password and we're going to paste it and we're just going to replace the label to say password and for this one we're just going to say password for the hint and kind of going back up to the top really quick we've got a background of this light blue we can keep it at that we've made the form fields have a white text so just be aware of the colors you're using we're not going to style this a ton again we're just trying to get some basic functionalities that we can get into the real nitty-gritty of the api methods and working with firestore but this will serve our purpose for now in our containers we need to give them first a decoration and we're gonna give them a box decoration and the reason why we wanted to give them a box decoration is i want to create some white buttons with rounded borders and to do that using a box decoration we can easily say border radius dot circular and give them a nice rounded border okay and then we can say color is equal to colors dot white the last thing we need to do is we need to give it a width which we can say media query dot of context dot size dot width divided by 1.4 and again what media query does is it gives us the width of the screen and it allows us to basically say okay no matter what kind of device you're using i want to give back a width based on the size of that device so it'll be unique to each device and this way it'll format nicely no matter what device it's being used on whether it's an ipad or an iphone or a google pixel no matter what kind of device it is it'll format it nicely and then we want to just give it a height of let's just say 40. uh 45 let's do 45 and then it's going to have a child of material button which will have an on press method which for now we're going to leave blank and the material button will have a child of type text which will say register we'll put register on top and we are going to actually just copy this container and use it for in and all we need to do is change this to login and we're good to go going back to our main let's click run open up my simulator here so you guys can see we're going to wait for it to build okay once that's built you should get something similar to this screen now the formatting of this is really ugly but you have seen that the padding on the sides of the buttons is about what we wanted so to resolve the issue of everything being pushed right at the top we're going to go to our column and we're going to say main axis alignment dot space between actually let's do space evenly and again we don't care too much about um how things look we're going more for functionality so putting space between it allows for space evenly it puts an equal amount of spacing and padding between each item so we've got email password register button login button okay so what we're going to do is we're going to test this out there we go okay those are working as expected and we are going to go ahead and check okay buttons or function is functioning as expected the next thing we need to do is we need to create our authentication methods to sign a user in and sign user up so we're going to go over to our firebase file so our flutter fire and we're going to create two methods the first one is going to be a future type of void and it's going to be called sign in and that's going to take a string of email and a string a password and the second one is going to be similar it's going to be called register so what we're going to do for our register method is we're going to do a try catch and for the catch i'm actually going to just paste in this exception handling for firebase so you'll see here firebase auth exception quick fix import that okay to put a space between these methods for clarity in this try statement we're going to say our wait firebase auth dot instance dot create user with email and password to which we're gonna pass in our email oh my goodness and we're gonna pass in our password here okay so let's go over what's going on right here so we're going to create an instance of firebase authentication and this has a bunch of different methods that we can access and we can utilize such as signing the user in verifying email there's a lot of different methods associated with firebase authentication the one we are interested in however is creating a user with an email and password as that is the method that we set up on firebase and all we have to do is pass an email password if it's successful things will go on it'll complete and we can enter the application just fine if however it throws an error then we know we don't want to route the user and it'll throw one of these exceptions right here it'll just print it to the console so what we're going to do is we're actually going to change this to a type of string response actually let's change it to a bool and what we'll do is if it's successful we can return true and if it's unsuccessful we'll just return false so we'll just say return false and we'll say return false after it prints out those logs now ideally we'll we would handle these exceptions and display the validation error that's occurring and in an even more ideal situation you would probably use the provider package or some other kind of state management to set up your authentication in a very smooth clean way if you were to publish this app this will work for our purposes it's totally fine nothing's going to break it'll serve our purpose so we're going to continue with this and the way that this is going to work is we are simply going to say when the user registers so that's this one let me put a comma after here for some formatting clarity we are going to make this an asynchronous method and we are going to say should navigate it's equal to await register and we're going to pass to it our email field dot text and our password field dot text and it's probably going to prompt us to import that one file okay and then what we're going to say is we're going to say if should navigate navigate which we'll get to here in a minute else actually we don't even need an else um for for now nothing will happen if you press it we'll just say nothing happens and we're going to just copy this because we're going to be doing something similar with our login so in login we're going to do the same thing except it will be sign in and this will be asynchronous as well and going back to our flutter file file we're going to change this to a type of boolean for sign in and there we go that's resolved now we still need to build out the sign in method so let's go ahead and do that again we're going to do a try catch statement and in this one i'm just going to put catch e for error and we're going to say print e return false if it's unsuccessful and we're going to try to do a wait firebase auth instance in with email and password and then we have our email and we have our password if this feels like i'm going too fast feel free to pause slow down or even check out the code i always put this code public on my github page and so if you'd like to check that out as well so you can follow along better by all means please do that and it's still upset here because we haven't put a return statement for inside the try so if it successfully hits this line that means no error was thrown when it signed the user up therefore we can return true and let the authentication page know hey you're good to go now that we've shelled out our authentication page let's create one more new view that we're going to use after authentication which we're just going to call home view and i'm going to make this a stateful widget called home view for child i'll just do a text with home view as that text we're going to need to import material there we go going to close that out i'm going to remove these files that we're not using and we're going to focus purely on the authentication routing to the home view so what we're going to do is we're going to say navigator dot push and this is going to take two parameters one of context and the other of material page route material page route has a builder method we're going to be using i'm going to say context and then we're going to say home view that is where we want to go okay add in home view let's add on some trailing commas here for formatting sake okay and i'm going to copy this navigator.push method i'm going to place it under register as well so if we successfully registered the user or log them in we should push and display our new page that we want to go to and what home view is going to be is it's going to be where we contain all of our methods for adding coins removing coins and viewing the current value of our coins going to start it up so we can see if it's working and we can test with firebase so let's go ahead and see if this works and if we have time we'll come back to this and we will make it a little bit better a little bit cleaner looking so i'm going to type in an email i'm going to give it a very simple password i'm going to say register and we've successfully gone into our home view now you may be wondering why is it a black screen with these double underlines and the reason for that is we currently are returning a type of container what we want to do is make this of type material i'm going to hot reload that page and now you'll see that we have a white background like we're expecting and the home view in the top left corner and actually what we're going to do is we're going to make this instead of material widget let's make it a scaffold widget and the reason for this is we want to use a floating action button to show the add button and scaffold has a nice built-in property for floating action buttons we're going to do that instead and in place of the body we're going to place a container let's give the container a width of media query dot of context dot size that size.width we want it to fill the space of the entire screen and for height we are going to do the same but instead of width i'm going to say dot height and let's go ahead and give it a decoration box decoration and let's do color colors dot white and then for child we can do our text hello world so before we go ahead and create the add and remove methods to connect to firestore let's go ahead and show out the ui for our home view so in place of this text widget what we're instead going to do is we're going to create a stream builder widget and stream builders have two parts the stream and what you want to do with the data that you get from the stream so to set up the stream we're going to say stream and then we're going to say firebase firestore dot instance dot collection and what we're doing right now is we're creating a path to the specific collection that we want to be listening to and watching and so we're creating a path to that and setting it as our stream users.doc the name of the document that we want to reference is firebaseauth.instance.currentuser.uid and then it's going to be a collection under that user called coins and then we say dot snapshots okay scrolling back to the left okay so this is the stream that we have set up we're basically going to tell the user to be or tell the stream builder to be looking at the user dock of the currently authenticated user and then to check out any documents under the collection coins and that's where we're going to be storing all the coins that the user has and so what we're trying to do with the stream builder is display a list of all the different coins that the user has and the most recent pricing and value of the coins that that user has and so the next part that we're going to do is we're going to add our builder aspect and the builder is going to have a couple of variables it's going to have a build context of context and we're going to have an asynchronous snapshot of type query snapshot called snapshot okay and let's see did i spell this right async snapshot oh i missed an s that's why it was not working for me it's a little confused there for a minute okay so these are the two arguments that it's taking and what we're gonna do is we're gonna say if not snapshot.hasdata return centered a circular progress indicator so what this will do is in the case that let me put comma here for formatting in the case that it is still trying to read in the data or it's been unable to process it quite yet it hasn't quite gotten the data it is going to return a circular progress indicator which will just keep on spinning until it gets data then what we're going to do is outside of this if statement we're going to have a list view that we're going to render that displays all the data because if we've passed over this if statement we know that the snapshot does have data so then we can do something with it so we're going to say return list view and the list view is going to have children of type snapshots dot data dot docs dot map and we're going to map those to a variable called document okay we're almost there and after it we want to say dot to list so we're going to list them out okay yes and then what we're going to do is inside of here we're going to say return container and the container is going to have let's say a row element or a row widget and it's gonna have two children we're gonna have um coin we'll call it coin name and then for the second one we'll call it um amount owned and this may all seem a little confusing at first but here in a second it's all going to come together and make sense and we're going to give this row a main axis alignment of let's do space evenly okay so let's discuss what's going on here so we've already talked about how if we passed over this if statement that means we have data so what we're doing is with that data we are taking that data and what it is is it's a list of documents found in firestore so what we're going to do is we're going to map them out and we're basically going to have this list view iterate through each document and with each document we're going to create and return a container and what we're going to do here is we're going to display right here we'll do it right now so we can see this so we're going to do some string interpolation here and we're going to say document dot id and the reason i'm saying this is because we're going to store the name of the coin in the id of the document so if you remember us talking about this we're going to limit how many types of coins the user can actually utilize and so because of this we're just going to store the name of the the name of the coin that the user has as the identifying value of the document and then what we're going to do here this is going to be a little bit more complex because what we have to do under amount owned is we need to take the so there's a value that we're going to be storing it'll be document.data and then it's going to be called amount but that's not the only value that we need to display here we need to multiply this by the current price of the coin on the market and so we're going to have to create we'll probably do it in the on inits state class on a net state method in this class but we're gonna have to fetch the current price of each coin and then what we'll do here is we'll basically say okay take the amount of that coin they have so let's say they have one tether coin and let's say tether is worth five dollars i believe it's worth one but for this example we'll say five we don't wanna display one here we wanna display five dollars because that's how much that user owns of tether so what we're gonna need to do is we're gonna need to have some business logic and a fun activity if you feel like this isn't complex enough for you or you want to take it a step further rework this whole project but utilize block provider river pods utilize some other kind of state management process so that you can perform the business logic in a much cleaner fashion we're going to do it here but it's going to be pretty rudimentary just so we can show how to access apis how to interact with firestore that's our main focus but if you want to challenge yourself and take this a step further try to implement some state management a more effective cleaner solution estate management into your example that's not the focus of this video however so we're gonna go past that so this is the general idea for now i'm going to keep it as this remember we said we're going to work out the ui first and then we'll come back to hooking everything up to firestore into the api so let's leave it like that for now and the next thing we need to do is let's find our scaffold let's see here here's our scaffold so we want to add a floating action button and what the floating action button is going to be is it's going to route us to a new page where the user can add in new coins and the floating action button is going to basically be our clean simple way of the user adding additional coins to the list and the reason why going back to the stream builder that we want to utilize the stream builder is that when we do an action like adding in a new value the stream builder will pick up the changes live from firestore and immediately render them in the view so we don't have to constantly be checking hey do you have more data hey do you have more data hey do you have more data the stream's just going to say hey i noticed a change in firestore let's update the ui so that's why we're doing a stream builder here okay for the floating action button we're gonna have two bits we're gonna have so let's create the floating action button we need to have an on press method which is where we're gonna route to that new file which we're gonna call add view and that's going to have our um our drop down with the different options of coins you can add and a form field where they can add in the number of coins that they want to add in and then we'll have a submit button so that's what's going to go in the unpressed and so let's actually work that out right now but we're going to say navigator dot push and it's going to take in a context and material page route and material page route has a builder that has a context which then calls our ad view unfortunately though we have not yet created the ad view class so it may not like this so what we need to do is we need to go here to our ad view and we need to say stateful widget and we're going to call it add view and for now it's just going to display a text add view we will come back to this next and we will be modifying this and i'm going to replace that container with a material widget okay going back to our home view it's no longer getting upset about that so our on pressed is good to go so now all we have to do is customize what is within the floating action button that the user sees in our case we want just a simple plus button that's kind of the uniform add button so we're going to go ahead and say child is equal to icon we can say icons dot add color of the icon will be white and let's give it a background color of blue okay i believe that's all we want to do there okay so this is all looking good we haven't quite hooked up our api method yet remember we're working out the ui first and then we'll go to that let's go over to our ad view and let's just shell out this ad view really quickly so what we're going to do with in the ad view is there's a couple of state variables that we need to establish we need to establish the list of different options that the user can select from and we need to create a string variable that's going to be equal to the value that the user has selected in addition to that we're going to need a text editing controller to be listening to and to capture the text input that the user puts for their number so what we're going to do here is in place of this text we're going to have a column okay that's our base widget that we're working with and we're going to have three elements we're going to have our drop down button our container um that is our input container and then we're gonna have a button and the button's really easy because we've already created a clean button on our authentication page for login so we'll probably just copy that button over and save us a lot of time but let's go ahead and work on the drop down button first the first thing we need to do before we can create that widget is we need to create the list of strings that we want to display so i'm going to call this coins and i'm going to set it equal to a list of three coins we're going to have bitcoin we're going to have tether and let's have uh ethereum there we go so these are our coins we're then gonna have a drop down value that's equal to bitcoin we're just to default it to bitcoin first one in the list now let's go down oh let's do one more thing i'm sorry text editing controller we'll call this a mount controller this equal to text editing controller just default it to that okay now we can add in our drop down button so let's go drop down button and the drop down button has a couple of elements we have our value which is going to be set to our drop down value and what this will do is whenever the user selects a new value in the drop down it will set well we are going to set the value of this drop-down value variable to the newest selected value which will in turn update the displayed value on that drop-down okay the next thing we need to do is we need to have our orange change method so unchanged has a value oops so what we want to do here is we want to say her let's actually let's specify it's a string what we want to do here is we want to basically just do a set state so we say set state and we want to set drop down value is equal to value and like we just mentioned we're going to replace the value of drop down value with the recently selected one and that'll in turn update our drop down button that's our unchanged now the only thing left is our items field so we've already listed out our items you see here it's expecting a list of drop down menu items so what we're going to do here is we're going to do coins which is the name of the list of different available coins that we provided then we're going to say dot map and we're going to say drop down menu item and it's drop down menu item of type string so we're going to add on that close the bracket then we're going to have a method in here that has an input of type string value okay we've got to be very careful with our commas and our closing brackets and make sure everything's working well okay and then what we're going to do and this isn't oh that needs to be a lowercase okay then what we're going to do in here is we're going to say return drop-down menu item type string and it's gonna have two variables we have our value and we have our child which we're just gonna keep it simple and just do text and display value for that text and close that with a semicolon i believe that's it we're going to test it here in a bit and see for sure if we got that right but so what we're doing is we're mapping out the different values in our list for each value we're creating a drop down menu item and the drop down menu item we can customize it however we want but in our case we're just going to keep it a simple text that displays the value that we're looking at so it'll say bitcoin tether and ethereum just a simple list with text fields or not fields they're just text text widgets okay so that's all i want for the drop down button the next thing is pretty simple we've done it already before we're going to do a text form field now we're going to constrain this one to a container that way we can if you remember when we did our first one on our authentication page we haven't put any padding on it yet and so it goes edge to edge and it looks a little funky so we're going to change that for this one and we're going to give it a width and we're going to say media query dot of context dot size dot width divided by 1.3 and then we're going to give a child text form field in that text form field we have our controller already set up which is a mount controller perfect we're going to give it a decoration of type input decoration and the reason for that is that we can give it a label and the label is going to say um how much of this coin let's keep it simple coin mount and i won't mess with the styling we'll just keep it simple on this one if you'd like to spruce up yourself have at it be a great practice in working on your styling skills and your widget formatting skills okay and i think that's all we want to do be really simple maybe we'll add a keyboard text input type dot number with options hmm let's do actually i'm going to keep it text i can't remember if number allows you to do decimals or not i think it might restrict it kind of like a phone number so we're going to just keep it as and actually let's just remove that entirely we don't really care for that right now maybe we'll go back and style that a little bit more later and as i mentioned in our authentication page we've already created a button so let's take this material button here whoa okay oops too much there we go copy that exit out of that close that guy paste instead of register we're going to say add and in this this is where we're going to call our firestore method for adding but we haven't set that up yet so we're not gonna worry about that quite yet okay so we've got our three fields our drop down our coin amount and our button for adding and after this we need to say navigator.ofcontext.pop and what that'll do is it'll remove this material widget from the screen and bring us back to the original screen that we were on which is home view okay i'm going to start this up and let's check it out okay so it's built and let's go ahead and log in and we're going to come back to this i don't like the styling whatsoever too spaced out not enough padding this text the black when everything else is white it's a little funky so we're going to come back to this as soon as we finish testing and getting this right and clean this up just a little bit log in okay this looks good there's nothing to display so i'm not very surprised we'll have to check it out once we're starting working with data and maybe we'll have to modify it a little bit and clean it up but for now this is great we've got our floating action button let's see if it navigates us okay and we're throwing an error type maps list iterable is not a subtype of type list okay so that'd be here in our ad view and i'm assuming it's this method right here ah we are missing dot two list let's go get ahead and give this a hard restart log in one more time and let's see if it works this time around perfect okay and i'm just realizing we can't see the drop down menu because it's it's hidden behind this so let's go up and for a column let's give it a main access alignment of center give it a quick restart don't need to restart the whole app okay this is looking good this is how we want it to look okay if i pull open the keyboard in the emulator this will work um maybe we'll tinker with the other keyboard types later and we got add and add for now just pops you nothing more okay so that's good i'm going to close that down and let's go back really quick to our authentication page and let's clean this up like i was mentioning earlier there's a couple things i didn't like so the first thing to do is the white we want to make it white not black so i believe that all we need to do is this [Applause] done okay first thing that was bugging me care of the next thing that was bugging me is the fact that these text form fields went end to end i want to put some constraints so that they're less so what we're going to do is we're going to just cut them we're going to place them inside of a container widget and we're going to give that container widget a width of media query contacts dot size dot width divided by 1.3 and we're going to do the same thing for the first one we are going to say child let's take the widget's width from that one and paste it into this one let's change this to center instead of space between and then let's just put some size boxes for now [Music] let's do media query of context size dot height divided by 35. that should be good just like a nice decent padding nothing too crazy put them between all of our objects so they aren't smushed on top of each other and [Music] i think we're good okay we're going to give this another run and let's see how those improvements look okay this is looking substantially cleaner than what we originally had so let's go ahead just do this one more time yep that looks great [Applause] i'm gonna remove this keyboard for my own sake log in everything is looking good okay let's close this down and let's shift over to our api methods and our flutter fire methods so we're going to start with our flutter fire methods first and we're going to be doing something interesting with our add method so we're not necessarily just creating a new document we're potentially updating at the same time so we need to know what is the current value of that's inside of that document and we want to potentially add on to that value if it exists so the way that we can do this with firestore is something called transactions so what we're going to do is we're going to run a transaction and essentially we're going to be opening up a document in firestore we're going to be reading the current value if it exists and then we're going to be adding on to that value and this way we can easily increment the number of coins that a user has so let's say i add one bitcoin today i come back tomorrow and i add .02 of a bitcoin now i don't want to replace the document with .02 i want to add on to the existing one so that the document reads 1.02 the transaction is going to help us do this so what we're first going to do is we're going to create a future method and i'm just going to make it a boolean and we're going to say add coin and the reason for it being a boolean is this is just a simple way of telling the client hey um it worked or it didn't work so we're going to turn true if it did false if it didn't because we're not necessarily needing any data on the front end from it all we want to know is was it successful in adding or not so we need two variables that we're going to be using for this ag coin i thought about it at first and thought about utilizing a coin class but it's really not real it's i thought about using a coin class at first but it kind of felt like we were pushing it a little bit when all we really needed were a couple of simple variables so what we're first going to do is we have string id and this is going to be the id of the document that we're going to be referencing and in the case that the document doesn't exist this will be the name of the new document that we're creating and then we're going to have another value called amount which is also going to be of type string the user when they input that number it's going to be a text string we're not going to bother on the front end worrying about formatting into a nice double we're going to handle that here in this method instead so we're passing it in as a string and of course because this is a future method and we are working with firebase there is going to need to be an asynchronicity to this method the next thing we want to do is we're going to do a try catch statement and if we fail if the try isn't successful and it catches an exception we're going to return false because it was unsuccessful in adding to the database and then what we're going to do is inside the try we're going to say string uid because we first need to access the document of the user before we can even think about accessing the documents for the coins so we say string uid is equal to firebaseauth.instance.currentuser.edu this will give us the uid of the current authenticated user we're then going to say var value is equal to double dot parse amount so we're we're taking our string and converting it into a double and if we have more time this is another thing that you can do in your free time you can add some validation to ensure that the string that's coming in is of a type double or simply we can add some validation logic to the front end on the add button to where we don't allow them to add until they format their number correctly and then what we're going to do is we're going to say document reference and what this is going to be is we're going to set this equal to the reference of the document that we want to update so it's going to it's going to basically be collection user document users uid collection coins document the coin id and that is going to be the path that we're giving this document reference object so we're going to say firebase firestore dot instance dot collection users sorry about that action.users.uid dot collection points dot dot id okay so that is our document reference and the reason we need to grab that is this is the crucial part of the transaction method that we're going to be using so now we're going to say firebase firestore dot instance dot run transaction and it's going to be instead of this okay it's going to be a method and it needs to be asynchronous okay and we're going to say document snapshot we're going to call it snapshot is equal to a weight transaction which is the value that run transaction produced for us transaction dot get and then we want to pass in our document reference okay okay making good progress here so now that we have our snapshot it's essentially a capture of the data within that document we can say if snapshot.exists so this means if there's not any data like not necessarily not any data but oh not exits exists um essentially what this means is this document does not exist already like we the user has not created a document for this coin yet so let's say we're adding bitcoin and the user's never had bitcoin in their profile it'll hit this clause okay so what we want to do here is we want to set a new document because um just because it didn't exist doesn't mean we don't want it to exist we want it to exist with our new value we just don't want to there's no other logic that needs to be put into play it's not like we're adding an old value as well so we're going to say document reference dot set and in here we can set amount equal to and we called it value and then we can return false actually we can return true i'm sorry about that don't know what i'm thinking then we can say double new amount so if the document already exists we want to first create the new value that we're going to update the document with so we want to say snapshot dot data and then we want to take the amount from that data and just for sake of consistency i'm going to replace that with singles single quotes plus value and then we are going to say transaction dot update and this is important we want to make sure we say update and we list what do we want to update what document passenger document reference which we establish here so we want to update this document and then we want to say what is what is it that we want to update within that document we want to update a mount and we want the value to equal new amount and we can say return true okay and before we do a semicolon close on this run transaction we can just say actually we can leave it at that you could do a then clause to basically say successfully updated but we don't care we're returning true and letting the user know hey all is good in the world okay so that is adding so let's go ahead and hook this up to our ad view so right here we want to say await and what did we call this method we called it add coin add coin and add coin takes in two variables the first one is going to be drop down value and the second one is going to be our amount controller and we need to import our flutter file file okay that's looking good now let's go ahead and give this another run and see if our stream builder displays the coin once we've added it and also make sure that it's actually even adding the coin in the first place okay let's go ahead and log in okay we currently have nothing we can confirm that go to add let's add ethereum let's do that let's say we're going to add 1.2 of ethereum we've added it okay now i'm a little concerned because i'm not seeing anything show here okay so you can see here that it is this it is inserting um the coin into the database but as we saw here nothing is showing so what we're going to do is we're going to run one more test let's add one bitcoin add it okay and let's go ahead and close this down run it again and while we're waiting for this to pull up let's go ahead and check out our home view and see maybe if we can find out what we are missing document.id document.data amount we're returning to lists there's no errors we're mapping the data there's no circular progress indicator so we know that we are getting something some kind of response let's check out add view really quick and let's see what or not add view let's check out our flutter fire there we go here's our issue so the problem is is that we gave a bad reference we were saying lowercase users but on our home view we were looking at the collection with an uppercase u so firebase is case sensitive so this is a very common thing that can happen so you want to always be sure that you're using consistency among titles i always do uppercase camel case with all my collections and that way i just remember it's always uppercasecamelcase don't even have to think about it so what we're going to do here we're going to restart it i'm going to go ahead to firebase and let's go ahead and sure enough you can see here users is lowercase i'm going to delete this collection just to reset my data okay and let's go ahead and check out this again see if we got it right this time log in let's add one bitcoin awesome bitcoin one let's add in point zero zero zero three of bitcoin add awesome now i do wanna cap it i don't want it to be so long i want to cap it at say two decimal places because i think what we'll do is we'll say well what we're going to do is we're going to represent this as a price so we're going to say this times whatever the current price is and so we will have to cap this the decimal places that's one thing we need to keep in mind but so far it's looking good let's do another one let's do tether as well say 54 tether okay awesome and you can see here it's starting to create a list so the next thing we're going to do is let's hook up to our api let's get that live pricing added in and then we can do a little bit more styling here and we'll be off to the races so let's go ahead and close this down okay so here's the api that we're going to be working with it's coingeco.com they have a free open to the public api that you can utilize unless you're using this for commercial purposes and really pinging it a lot it should be perfectly fine to use so for our case where we're gonna have a low amount of users um we're not expecting a ton of people this is gonna be just fine so we have this get request um it takes in an id of a coin the way that coingecko does their ids i've already looked into this a little bit it's the name of the coin so we have bitcoin tether ethereum so the id that we have in our documents we can utilize that for this api call as well hence why we stuck with the lowercase coin name for the id and everything it just it flows well working with the api so what we're going to do here is let's go ahead and test it out so let's click try it out we're going to pass bitcoin click execute awesome and you can see here here's the data we're getting back now the only data we really care about is the price so let's look down let's see here this is description in different languages okay here we go okay this is what we care about market data then within market data there's a field called current price then within current price there's a field usd for us dollars so this is what we care about with this api and this is what we're going to try to capture so let's go back up to the top we're going to grab this request url i'm going to copy that i'm going to place it right here and the next thing that we're going to do is we need to import the http library in order to do that i believe i've already done this on this project but we're going to go to our pubspec.yaml file yep and you are going to add in http under dependencies just place it right with your other flutter fire dependencies um or just under and then you're going to use the latest version which as of date of this video it's 12.2 okay um yes okay so we've now got that let's import http and we're gonna say as http and then we're going to say future double and we need to import one more thing oh thinking yeah there it is the convert library okay future double i'll call it get price and it takes in an id okay so we're returning a double which is the price that the user is asking for okay so the way that this works is we're going to do a try catch cover our bases here if we catch an error we're just going to print the error console and we're going to return zero and so if you see that the current value of a coin is zero then you know that you probably did something wrong um okay and we're just going to print the error to the console if we catch an error the next thing we're going to do is we're going to say var url is equal to and let's go ahead and copy this url paste it and the reason i'm leaving off the ending is we're going to add on id to the url okay the next thing we want to do is we want to say var response is equal to http dot get url and what this will do is it will perform a get request as if we were working at a postman or putting this url api into the browser it's essentially doing that and it's setting the response of that object to this variable called response we're then going to have a variable called json which we're going to say json to code and it's going to say response dot body so what we're doing is with the okay why doesn't it like this response to body hmm ah that was incomplete that's why okay so what we're doing with this is we're saying take your response object and with your response object i want to take the body element and i want to format it in json format and what we can do with this is we can then say value is equal to json and i believe it was called market data let's confirm yep market data oh not dot i want to do another one of these it's called current price current price usd and let's just for consistency's sake we don't want to trust the api to make the correct decision with formatting so we can trust ourselves so we're going to format it as a string and then we're going to say return double dot parse of value and the reason i say that is i've seen apis before that are poorly managed and kept and sometimes they'll return a double sometimes return to string sometimes they'll turn in int and it can cause a lot of problems if you're not ready for that so i find it best just to take matters in my own hand make sure we have a uniform string that we're reading and then do with the string as we want afterwards so what this will do is this will return the price of the coin that we're dealing with so now what we want to do we're done with add view we're going to go back to our home view and we're going to manipulate this a little bit okay so the way that we're going to work with this data is we're going to do the following we're going to say double bitcoin is equal to 0.0 do the same for ethereum and for tether then we're going to override our init states and what we're going to do is we're going to say get values and then we're going to have get values be asynchronous and the reason for this you can't do asynchronous methods with an init state so we're going to create a simple method that's called add a net state to go and grab the newest values for each of these coins and we're going to say um bitcoin is equal to get price of bitcoin this needs to be a weight and we're gonna do the same thing for ethereum and for tether then we're going to call set state just to make sure those get set okay okay so what we're doing is when the page initially loads we're going to go ahead and call our api method and get the current price for each of these three coins that the user could potentially show and then what we're going to do is we're going to have another method within our widget that's going to be called get value but this one's going to have parameters it's going to have a id and it's going to have a double of type amount and what we're going to do here is we're going to say if id is equal to bitcoin return um bitcoin times amount else if id is equal to ethereum return ethereum times amount and otherwise it must be tether so return tether times amount okay so what we're doing here is we're going to be calling this from within our individual rows to get the current price and so we're going to say okay get the current price of bitcoin and multiply it by whatever amount that you're passing me that the user owns of that and so we're going to say pass the coin you're looking at and we're going to check and see which one it is and then we're going to multiply the current price of that coin by the amount of that coin that the user owns so utilizing this method we're going to go down here into our stream builder go into our list view and for amount owned we are now going to say um get value oh my goodness i'm having trouble here it's gonna be document.id and then the second variable is the amount of that coin okay we want to put a dollar sign in front of it and we want to say dot to string or let's do two fixed or that's what it is to string as fixed and let's go to two decimal places so this will make sure that if our number that we get back our double has like two plus like it could have like five decimal places we want to make sure we only show two so it looks like a legitimate number and keep in mind that this is in u.s dollars if you'd like to use a different currency you can look at the api documentation you can figure out which one is represented is represents your country so for example we have the euro i believe canada is in here cad it has pretty much every common well-known currency um on here that it can compare to okay so let's go ahead and test this out and make sure that it is giving us the proper price and so we're going to run this and while we're running it we're going to go ahead and check out firestore really quick give it a refresh and let's see roughly what we think it should equal so we have and eight tether coins let's see tether to dollar okay one tether is about one dollar so we should see about 108 for tether and for bitcoin we have okay let's see one bitcoin price and we should see 10 800 to 10 900 somewhere in there for bitcoin let's pull up in our emulator let's log in awesome perfect not exact well actually what do i know i um i was given a rough estimate but it looks like that's correct like that's the amount that we want to have so the last thing we need to do is let's go ahead and give these some styling and then maybe we can even add in like a x icon and if they hit it then we just sell everything we just clear out that coin just so you can get familiar with how to delete things from a document okay and going over really quickly when it comes to deleting if you want to allow the user to delete up to a certain amount like i just want to sell half of my bitcoin what you're going to do is you're going to do something similar to the transaction that we did with adding coins but instead of adding onto you will subtract the amount that you want to do from that coin so it's a very similar method for this example just to wrap it up and make it concise we're going to just say delete all so let's manipulate this this container here so the first thing we can do is we can give it some decoration give it a box decoration we do border radius dot circular let's do 15 we can do so unique coloring so we can say color is equal to colors.blue um we can do let's do some text styling here let's say text style color as we go to colors.white and let me go here and again i'm going to be putting all of this code i'll be putting all this code online and so if you have any questions or wanna or you wanna slow it down a little bit and get a better feel for it you can always go back and check out that code okay oh i'm sorry i forgot the key part of styling is the style tag i was wondering why i was getting a little error there okay that's good um we're gonna wrap this whole thing so container we've given it a width have we we have not given it a width oh we have no we haven't okay sorry for the back and forth let's give it a width let's give it a height give it a hot reload i'm sorry i meant restart hot restart okay looks good now we need some padding um let's do container return padding childish container and padding the edge insets dot vertical only top five looks good um i'm still slightly confused as to why this isn't working the way i want it to the sizing isn't how i want it um let's do this instead let's do left 15 right 15. okay that looks good that looks good to me okay let's go ahead and add that button add that button button i'm sorry my mouth is getting a little dry okay let's go ahead and add that button and what i'm going to do to create a little bit more room i'm going to delete this i think it's pretty self-explanatory when you see the dollar sign and i don't think we need to include name so we're trying to do is we're just trying to free up a little bit more space to include that button and we're gonna have an icon here icons dot close maybe i'm not 100 sure what that icon looks like and then we're going to say color colors dot red [Applause] and actually now that i think about it we need an icon button okay on pressed let's just print something so we can test it okay um i'm going to say space between just make it a little bit cleaner that looks good we want some spacing on the left of those coins and we on it up the font size so first font size um let's say 18. and add in that padding on the left so the way we can do this is we can just put a size box of type width 5.0 just the left of that first item reload it look at it looks good to me so we've got that padding on the left the x's will always be on the right let's see if that was printing or not output there we go debug console that was what i was looking for let's try this again okay that's good so now we can move on to our remove method so let's go back to our flutter fire let's create a future method type bool we'll call it remove and we'll pass in an id and we're going to say remove coin actually so we're first going to do is we want to get the user's uid so we've already done this up above get the current uid of the user then what we're going to do is we're going to say firebase firestore dot instance dot collection users dot doc uid dot collection and we're gonna say once again um coins dot doc id and then we're going to say dot delete what this will do is it will delete that document from our list okay so now all we have to do is we need to reference it oh i'm sorry and return true now we have to do is go back to our home view within our icon button we can say async and then we're just going to say await or we call it remove coin and we want to specify the coin we want to remove which is going to be document.data actually not even.data document.id and then we need to import our flutter fire into this page into this dart file okay we're gonna do a hard restart and we're gonna try this on our tether coin okay it's gone from our list but let's double check and make sure it truly removed it and it looks like it did now let's try it with bitcoin let's go back to firebase and it removed bitcoin as well awesome let's go ahead and just add in perfect okay so we've successfully completed our crypto wallet clearly there's always a lot of other things that you can do with this um if you'd like to challenge yourself a little bit more i would suggest doing the following things one incorporate some more advanced business logic state management into the app two establish some classes and work on api usage and improving how you utilize responses and three work on the styling you can never learn too much when it comes to flutter styling i hope that this is a good app to break you in and get you comfortable working with firestore firebase authentication and basic api usage it's really not as hard as some people make it out to be i hope that you felt the same way doing this tutorial with me once again i'd like to thank free code camp for giving the opportunity to teach you guys and show you guys how to utilize firebase in your flutter application and as always i'll catch you guys next time thanks for joining me
Info
Channel: freeCodeCamp.org
Views: 71,862
Rating: undefined out of 5
Keywords:
Id: fi2WkznwWbc
Channel Id: undefined
Length: 95min 7sec (5707 seconds)
Published: Mon Oct 19 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.