0 1 00:00:00,680 --> 00:00:01,020 All right. 1 2 00:00:01,050 --> 00:00:07,230 So, now that you've successfully incorporated Firebase into your project, it's time to actually use it 2 3 00:00:07,440 --> 00:00:09,510 and register some users. 3 4 00:00:10,080 --> 00:00:12,930 So this is currently how our app looks. 4 5 00:00:13,050 --> 00:00:18,690 And, essentially, what we're going to be doing is from this registration screen, we're going to be getting 5 6 00:00:18,690 --> 00:00:25,080 the user to type in their email and their password. And once they've done that, we're going to--when they 6 7 00:00:25,080 --> 00:00:32,730 press the register button, we're going to route this request through Firebase. And, essentially, we're asking 7 8 00:00:32,730 --> 00:00:39,450 Firebase to keep a note of this user's email and to encrypt their password. 8 9 00:00:39,480 --> 00:00:45,450 Now, once they're done and this was successful, then we're going to take them straight to the chat screen 9 10 00:00:45,750 --> 00:00:50,850 where they're going to be able to see the messages that's associated with their account. 10 11 00:00:51,270 --> 00:00:55,720 So let's go ahead and try this out. Now, in order to figure out how to do this, 11 12 00:00:55,740 --> 00:00:59,630 we're going to use the Firebase Getting Started Guide for iOS. 12 13 00:00:59,700 --> 00:01:06,120 And if you don't have that link, then you can simply just go to firebase.google.com/docs/ios 13 14 00:01:06,180 --> 00:01:12,660 and here if you scroll down, you'll see a section called Authentication. 14 15 00:01:12,660 --> 00:01:15,510 We're going to select iOS as our platform. 15 16 00:01:15,510 --> 00:01:22,350 Now, we're going to be using password authentication which ask the user for an email and a password 16 17 00:01:22,740 --> 00:01:27,860 and they're going to need their email address and password later on to be able to log in again. 17 18 00:01:27,960 --> 00:01:33,720 Firstly, we've already done this part where we've added Firebase to our project. 18 19 00:01:33,750 --> 00:01:40,840 The next thing we have to do, though, is we have to enable email and password sign in our Firebase console. 19 20 00:01:40,890 --> 00:01:46,420 So let's head over to our Firebase console and go into our project Flash Chat iOS13. 20 21 00:01:46,450 --> 00:01:55,480 And here we're going to click on the Authentication tab and click on sign in method, 21 22 00:01:55,480 --> 00:01:59,570 and then we're going to edit this email and password method of signing. 22 23 00:02:00,100 --> 00:02:07,750 So we're gonna go ahead and enable it and click save. So, now that this is enabled, we can go back to the 23 24 00:02:07,750 --> 00:02:10,930 documentation and we can proceed to the next step. 24 25 00:02:11,530 --> 00:02:18,760 So, first, we need to import Firebase in our ApplicationDelegate and you should have already done this 25 26 00:02:18,850 --> 00:02:20,700 in the last session. 26 27 00:02:20,710 --> 00:02:27,280 So just check that you've got Firebase imported and you've got the FirebaseApp already configured and 27 28 00:02:27,280 --> 00:02:30,240 connected to the Firebase servers. 28 29 00:02:30,280 --> 00:02:38,950 So, now that we've done steps one and two, the next step is to go ahead and add this line of code where we 29 30 00:02:38,950 --> 00:02:47,380 use the authentication module from five days to create a new user using an email and a password. 30 31 00:02:47,380 --> 00:02:55,450 So notice how these two inputs, these two arguments, we have to supply. And in our case, we want to do this 31 32 00:02:55,510 --> 00:03:03,670 inside our RegisterViewController in the moment when they press on the register button which is this 32 33 00:03:03,670 --> 00:03:05,060 one right here. 33 34 00:03:05,080 --> 00:03:06,770 So they're going to type in their email, 34 35 00:03:06,790 --> 00:03:11,830 they're going to type in their password, and then they're going to press on the register button and we're 35 36 00:03:11,830 --> 00:03:13,880 going to trigger this line of code. 36 37 00:03:13,960 --> 00:03:21,190 So let's go ahead and copy this line of code and paste it inside our IBAction and delete this comment 37 38 00:03:21,190 --> 00:03:22,470 right here. 38 39 00:03:22,540 --> 00:03:26,230 Now, notice how as soon as we do that, we get some errors. 39 40 00:03:26,260 --> 00:03:29,980 Firstly, it tells us that it doesn't know about "Auth." 40 41 00:03:30,280 --> 00:03:33,260 So Auth, of course, comes from the Firebase module, 41 42 00:03:33,310 --> 00:03:40,510 so just as what we did in the app delegate, we have to import the Firebase module here, so it knows about 42 43 00:03:40,510 --> 00:03:47,080 this authentication module which contains a createUser with email and password method. 43 44 00:03:47,080 --> 00:03:52,300 Now, the next two errors are easy because it tells us that it doesn't know what email is and it doesn't 44 45 00:03:52,300 --> 00:03:54,520 know what password is. 45 46 00:03:54,520 --> 00:03:59,860 So in this case, the email that we're going to use to register the user is going to be based on whatever 46 47 00:03:59,860 --> 00:04:02,500 they typed into the email text field. 47 48 00:04:02,530 --> 00:04:07,820 So in here we're going to create a constant code email 48 49 00:04:07,880 --> 00:04:15,100 and we're going to set it to equal emaiTtextField.text and the password is, of course, going to be from 49 50 00:04:15,100 --> 00:04:17,980 the passwordTextField.text. 50 51 00:04:17,980 --> 00:04:23,890 Now, notice how even as I'm typing this text property that it's telling me that the text displayed by 51 52 00:04:23,890 --> 00:04:29,380 the text field is not a string but an optional String denoted by that question mark. 52 53 00:04:29,380 --> 00:04:36,010 So I can't simply just leave it as this because I'm gonna get the error telling me that the optional 53 54 00:04:36,010 --> 00:04:42,190 type String which refers to this one must be unwrapped to a value of type normal String in order for 54 55 00:04:42,190 --> 00:04:45,880 it to be used as an input to the email parameter 55 56 00:04:45,880 --> 00:04:48,310 and the same thing with password. 56 57 00:04:48,310 --> 00:04:55,240 So we can use what we learned about optional binding in order to turn the emailTextField.text 57 58 00:04:55,330 --> 00:04:57,160 into a real string. 58 59 00:04:57,340 --> 00:05:06,010 So to do that, we add the word "if" in front of the "let" and I'm going to chain these two things together. 59 60 00:05:06,010 --> 00:05:12,400 Let email = emailTextField and let password = passwordTextField.text by adding 60 61 00:05:12,490 --> 00:05:13,990 a comma here. 61 62 00:05:14,050 --> 00:05:22,360 What this does is it says if emailTextField.text is not nil and it can be turned into a string 62 63 00:05:22,840 --> 00:05:30,220 stored inside this property called email, and the same thing with password. And only if both of these 63 64 00:05:30,220 --> 00:05:38,700 things do not fail, then do we continue on to the next stage which is to actually create our user. 64 65 00:05:38,770 --> 00:05:41,020 Now, you'll notice that inside here, 65 66 00:05:41,050 --> 00:05:47,410 email is now a normal string and so is password. This way. 66 67 00:05:47,410 --> 00:05:55,090 we've done optional chaining on two optionals and they both have to not be nil for this "if" statement 67 68 00:05:55,090 --> 00:05:57,970 to be carried out. And in our case, that makes sense. 68 69 00:05:57,970 --> 00:05:59,260 We can't have a nil email. 69 70 00:05:59,290 --> 00:06:04,180 We can't have a nil password if we want to create our user. 70 71 00:06:04,280 --> 00:06:09,320 So, now inside this closure, we get access to two things. 71 72 00:06:09,320 --> 00:06:17,120 One is the authentication result which you'll see from the documentation that this is the user's account 72 73 00:06:17,120 --> 00:06:20,650 data after they've been successfully registered. 73 74 00:06:20,660 --> 00:06:27,480 The other thing we get back is an error if there is one. And this error is an optional as well. 74 75 00:06:27,620 --> 00:06:35,450 So, say, if I tried to just simply print this error, you can see that it's actually an optional error type. 75 76 00:06:35,450 --> 00:06:42,860 So what we're going to do instead is we're going to, again, invoke our trustee if "let" to optionally bind 76 77 00:06:43,280 --> 00:06:48,620 a new constant, which I'll call "e" to the error. 77 78 00:06:49,040 --> 00:06:54,740 So this is an optional and we're going to turn it into a nonoptional if indeed there was an error, 78 79 00:06:54,800 --> 00:07:00,390 so if error was not nil. And in this case, we're simply going to print the error. 79 80 00:07:00,410 --> 00:07:06,470 Now, if you wanted to build out this app for deployment instead of, say, for learning, then you might want 80 81 00:07:06,470 --> 00:07:10,690 to think about the ways that you can relay this error back to the user. 81 82 00:07:10,730 --> 00:07:17,570 Say, for example, creating a pop-up or a heads up display like we did previously. But in my case, I'm just 82 83 00:07:17,570 --> 00:07:23,030 going to print it for me as a developer to know if there were any errors that were triggered. 83 84 00:07:23,870 --> 00:07:31,190 Now, the next thing is I'm going to add an "else" in here because if there were no errors or if error is 84 85 00:07:31,190 --> 00:07:35,790 equal to nil, then this block is going to get skipped and we're going to fall into here. 85 86 00:07:36,080 --> 00:07:40,880 In that case, then I've successfully registered my user without any errors. 86 87 00:07:41,000 --> 00:07:50,870 So what I want to do is I want to navigate to the ChatViewController. So how do we do that? 87 88 00:07:51,290 --> 00:07:57,650 Well, if you remember in our Main.storyboard, we've already set up a segue between the Register View 88 89 00:07:57,650 --> 00:08:04,430 Controller and the Chat View Controller. And the segue should have an identifier called 89 90 00:08:04,430 --> 00:08:08,270 RegisterToChat with a capital "R." capital "T," and capital "C." 90 91 00:08:08,330 --> 00:08:14,930 So I'm going to copy that and I'm going to use it to trigger a segue inside this "else" block. 91 92 00:08:15,410 --> 00:08:23,530 So I'm going to call the method performSegue which is down here withIdentifier and the identifier 92 93 00:08:23,530 --> 00:08:29,030 is, of course, that string that I copy just now which takes the user from the register screen to the chat 93 94 00:08:29,030 --> 00:08:35,090 screen, and the sender is gonna be "self" because this is the origin of that segue. 94 95 00:08:35,180 --> 00:08:40,090 It's attached from the Register View Controller to the Chat View Controller. 95 96 00:08:40,370 --> 00:08:48,770 And, of course, because we are inside a closure as denoted by this "in" and this syntax here, then we, 96 97 00:08:48,770 --> 00:08:54,420 of course, have to add the word "self" in front of any methods that we're calling on the current class. 97 98 00:08:54,470 --> 00:09:03,060 So let's go ahead and add that and we should now be error-free and ready to test our app. 98 99 00:09:03,230 --> 00:09:03,510 All right. 99 100 00:09:03,540 --> 00:09:10,620 So I'm gonna go over to the Register screen and I'm going to type in an email and password to register 100 101 00:09:10,620 --> 00:09:11,460 with. 101 102 00:09:11,460 --> 00:09:18,270 So, usually, with Firebase, they have certain rules just like you would find on any other service that 102 103 00:09:18,270 --> 00:09:25,470 says a valid email must have some letters or numbers, and then an "at symbol," and then some more letters 103 104 00:09:25,470 --> 00:09:30,580 and numbers, and then a .com or .co.uk, or something like that. 104 105 00:09:30,600 --> 00:09:38,940 So the simplest way to make sure that this is valid, I tend to test using something like 105 106 00:09:38,940 --> 00:09:40,350 1@2.com. 106 107 00:09:40,440 --> 00:09:41,540 And then the password, 107 108 00:09:41,550 --> 00:09:44,340 I'm just going to use 1, 2, 3, 4, 5, 6. 108 109 00:09:44,460 --> 00:09:48,050 Now, Firebase also has some rules on passwords. 109 110 00:09:48,210 --> 00:09:53,230 One of these rules is that the password must be at least six characters long. 110 111 00:09:53,260 --> 00:10:00,300 And notice how the password field is being obscured because in our Main.storyboard when we added that 111 112 00:10:00,300 --> 00:10:08,460 Password TextField in the attributes, we selected Secure Text Entry and you should do that for the password 112 113 00:10:08,460 --> 00:10:13,560 fields that you create in your apps, so that other people when they're looking over your user's shoulders, 113 114 00:10:13,770 --> 00:10:16,620 they're not going to be able to see your user's password. 114 115 00:10:16,710 --> 00:10:25,290 So, now that we've done this, let's go ahead and click Register. And now because the registration process 115 116 00:10:25,290 --> 00:10:29,150 was successful, we got taken to the Chat View Controller. 116 117 00:10:29,160 --> 00:10:34,870 This one right here. And we didn't get any errors printed in here. 117 118 00:10:34,890 --> 00:10:41,580 Now, you might say. "But wait a minute, I do see an error. I see something in my console that's about the 118 119 00:10:41,640 --> 00:10:43,540 iCloud Keychain. 119 120 00:10:43,560 --> 00:10:50,400 Well, this is actually a warning from the iOS operating system and it's because we're testing our app 120 121 00:10:50,520 --> 00:10:57,960 using a secure entry field for passwords, but we're doing it on a simulator where we don't have the user's 121 122 00:10:58,020 --> 00:11:00,390 iCloud Keychain details. 122 123 00:11:00,390 --> 00:11:07,120 This is not an error from Firebase Authentication. And this is trying to tell you that you can use a 123 124 00:11:07,120 --> 00:11:13,370 iCloud Keychain to suggest the user a automatically created strong password. 124 125 00:11:13,440 --> 00:11:18,020 But in our case, we're not too bothered about this AutoFilling process. 125 126 00:11:18,060 --> 00:11:24,420 So I'm just gonna ignore this warning message and it's not going to affect your app in any way. 126 127 00:11:24,420 --> 00:11:29,340 And up here, I've got some more printouts which actually come from my WelcomeViewController. 127 128 00:11:29,730 --> 00:11:35,130 So I'm gonna disable all of these print statements and delete them because we're now done with that 128 129 00:11:35,130 --> 00:11:36,410 part of the section. 129 130 00:11:36,480 --> 00:11:42,090 Now, you might have kept the CLTypingLabel, so you won't get these print statements. But in my case, 130 131 00:11:42,120 --> 00:11:44,990 I'm just going to simply delete them. 131 132 00:11:45,030 --> 00:11:51,150 So now that we've bypassed this error message which means we've successfully registered our user, 132 133 00:11:51,150 --> 00:11:59,340 we can also head back over to our Firebase console. And if you select your project and go to the Authentication 133 134 00:11:59,340 --> 00:12:04,910 tab, you'll see that under the Users tab, you've now got a brand-new user. 134 135 00:12:05,160 --> 00:12:12,150 And as convention with secure authentication, you should only be able to see your user's emails. 135 136 00:12:12,150 --> 00:12:17,020 You should not be able to see a text version of their password. 136 137 00:12:17,310 --> 00:12:25,380 And this is because if you store a user's password as plain text in any sort of database, it makes it 137 138 00:12:25,560 --> 00:12:30,360 really prone to hacking. And you don't want what happened to Ashley Madison to happen to you. 138 139 00:12:30,720 --> 00:12:37,950 So in this case, we're actually offloading this burden of securing the user's password to Google who 139 140 00:12:37,950 --> 00:12:40,800 are pretty much expert at stuff like this. 140 141 00:12:40,800 --> 00:12:47,850 So that means all of your user's passwords are going to be securely encrypted and stored safely. 141 142 00:12:47,850 --> 00:12:55,080 And you don't have to think about cryptography or encryption or hashing or any of that stuff, it's all sorted 142 143 00:12:55,080 --> 00:12:55,680 for you. 143 144 00:12:56,430 --> 00:13:03,210 So now that we've successfully registered our first user using the Firebase Authentication module, let's 144 145 00:13:03,210 --> 00:13:07,860 go ahead and see what are some potential problems that can happen in this process. 145 146 00:13:07,860 --> 00:13:14,940 Let's say that if I decided to register my user, and remember how I told you previously that you can't 146 147 00:13:14,940 --> 00:13:20,100 actually have a password that's less than six characters long. 147 148 00:13:20,130 --> 00:13:27,030 So if I just put in 1, 2, 3, 4, and I click register, you can see that in the console, I get an 148 149 00:13:27,120 --> 00:13:27,850 error. 149 150 00:13:28,080 --> 00:13:34,260 And in the app, I don't get to proceed forwards into the chat screen. 150 151 00:13:34,260 --> 00:13:35,910 So what's this error all about? 151 152 00:13:36,210 --> 00:13:41,160 Well, it says that the password must be six characters long or more. 152 153 00:13:41,160 --> 00:13:47,580 So if you wanted to, you can actually happen to the property called localizedDescription. 153 154 00:13:48,180 --> 00:13:57,330 And this is a description of the error that is localized to the language that the user has selected 154 155 00:13:57,330 --> 00:13:58,740 for their iPhone. 155 156 00:13:58,770 --> 00:14:01,890 So if they're based in Spain, then this should be in Spanish. 156 157 00:14:01,980 --> 00:14:07,990 And if the phone is set to French, then it should display the description of the error in their own language. 157 158 00:14:08,560 --> 00:14:14,620 And this is really useful because you can use this localized description which doesn't contain all of 158 159 00:14:14,620 --> 00:14:19,150 this funky stuff about error codes or, or, or anything like that. 159 160 00:14:19,360 --> 00:14:25,660 Instead, it has something that the user can understand such as the password must be six characters long 160 161 00:14:25,720 --> 00:14:31,870 or more, and that gives them really good feedback as to why it is that the app is not working and taking 161 162 00:14:31,870 --> 00:14:33,660 them through to the chat screen. 162 163 00:14:33,730 --> 00:14:39,790 Now, this module is long enough as it is. But if you wanted to, you could actually put this string into 163 164 00:14:39,820 --> 00:14:45,700 a label, say, somewhere up here or somewhere down here, wherever you like, or even a pop up if you wanted to 164 165 00:14:46,120 --> 00:14:51,430 to give the user some feedback as to why the app is not letting them continue. 165 166 00:14:52,270 --> 00:14:58,210 So, now that we've managed to register our very first user: 1@2.com, 166 167 00:14:58,540 --> 00:15:04,200 the next step is to log in this user, right? In the next lesson, 167 168 00:15:04,240 --> 00:15:11,320 we're going to be tackling the login route of our app, and we're going to be using the Firebase Documentation 168 169 00:15:11,590 --> 00:15:16,370 to try and get our login working for this user and their password. 169 170 00:15:16,460 --> 00:15:17,960 We're going to go through it together. 170 171 00:15:18,040 --> 00:15:20,410 So all of that and more, I'll see you there.