 Hello, my name is Matt Ravel and today I'm going to show you how to build a mobile application with React Native and Spring Boot. This screencast is based off a tutorial that I wrote and published back in October of 2018, but I've also kept it up to date, so it's using the latest and greatest version of React Native and J-Hipster. The source code for this project is available on GitHub, and in this project you'll see there's a demo.adoch. This file, you'll see right here, is a script that basically shows how to create this tutorial with the minimal steps needed. The project that I'm going to create is based on 21 points. 21 points help is an app that I wrote as part of the J-Hipster book 5.0 that allows you to basically track your help. And so it has a user, it has points, weight, and blood pressure, and how it works is you'll basically enter in points for each day. You get a point if you exercise, you get a point if you eat well, you get a point if you didn't drink any alcohol, or maybe you just had one glass of wine, and then you can also add your weight or your blood pressure. So this is an app that I use and you can see here at 21points.com where I can add in points for a specific day, or I could add in my blood pressure, or I could add in my weight. And so that's how the whole thing works. So what I've done is I've exported the JDL for this into the sample JDL project, JDL samples. And so JDL is J-Hipster domain language, and what this allows you to do is define an application that has various things like OAuth2, Postgres, Gradle, Elasticsearch. So if you want to know more about that, that's just kind of a J-Hipster thing, not so much a Spring Boot thing, but we can copy the code from this and go back to our tutorial. And we'll start. First of all, you have to make sure you have J-Hipster installed. So I already do, and I can do J-Hipster version, and you can see I'm using 580. I can create a directory to hold my application, and we're going to have an API and an app. So I'm going to call the API J-Hipster API, so we'll do React Native Spring Boot J-Hipster API. Oh, I forgot the dash P. And then I'll CD into there and VI this app JH and put that JDL in there, and then I'll go into the J-Hipster API directory. And this is how J-Hipster works when you're creating monoliths, is you want to actually be in a new empty directory and create your application from there. So you can just type J-Hipster and it'll prompt you with a number of questions, but since I've already defined them in my JDL, I can do import JDL and point to that file. So that's created a whole bunch of code for me and generated the entities and their screens and tests that they need. So I would like to see what the code coverage looks like. So I'm going to start by running this sonarCube command, but before I do that, I'm going to start all the Docker containers that we're going to need. Those are all included with J-Hipster. Now I can run clean test and send all the results to sonar. And we can open that up at localhost 9001 on the project to be analyzed. You'll see health points as AAA rating and 70% or 71% code coverage. So not bad, eh? Back to our steps. The next step is to add a React Native application. So I already have Ignite CLI installed. So if I run Ignite version, you can see 222 is installed so I can do Ignite new health points. And the reason I'm calling it health points is that's what I want the name to be in the application itself. I will actually rename that directory after this is created. So we'll specify the path to our J-Hipster project directory, which is J-Hipster API. And then it finds a config file and asks me if I want to enable end-end tests. I'll just accept the default. And then one thing you should know is that this does create a git directory. And so if you're trying to save both projects, it's actually better to just delete this one. And then I'm going to rename the directory health points to React Native app. And then we'll go ahead and add it. Or we'll do a git init on this parent directory and make sure we have everything. Oh, that's because we have one in this one as well. Okay. So now we're at a stage where we have all those files added and we can say add React Native app. And this does create a couple of files on the server side that allows basically a client like a React Native app to talk to J-Hipster. And so what it does is it sets up a resource server on the Spring Boot API and that allows us to talk to the backend with just a jot. Just to show you that the backend does work, first thing I want to do is restart Docker because it made some adjustments to the basic Docker configuration to allow implicit flow with OA. And that will allow the client to talk to it. And then I'll go ahead and start the server. So you can do J-Hipster API, start with Gradle W. And while that's going, I'm also going to go into the React Native client and run pod install in the iOS directory. And then we can run React Native, run iOS. So you can see that can take some time, the first time around three minutes, 37 seconds. What I would like to show you is that you can go to this local host. You can sign in to the Spring Boot API that's generated by J-Hipster and it'll log in to Key Cloak and everything works. And then you can see your entities. So if we were going to go to points, we could create a new point and say, hey, today, January 28th, I exercised, I ate well. And it's a happy Monday. And then we could assign that to the admin user. So you can see it saves everything in there. And this is a React UI. That's what I chose when I created it. And then if we go back to our simulator, you can see our app is here as well. And it'll prompt us to go to, I believe this is because we have local host specified. When we switch to Octave, it'll actually say the domain name there. And then you can put in admin, admin. And we're logged in now, and you can go to entities. And we haven't generated any entities for this client, so let's do that. In this project, we can do, let me get the command here. It's generate import JDL. I do want to let you know that if you want to run on Android, you can, you just have to use React Native Run Android. You have to have Android Studio running, and you have to have an AVD running. And then you have to do some mappings of ports. That's why I'm using iOS. It's just a little simpler for this specific example. So I'm going to import those same entities. And you'll notice it actually generated not only the entities themselves, but also tests. So that's pretty slick. And I can go back to my simulator and hit command R. And all those entities should be there now. And if I click on point, you'll see the one I entered on the client is actually there. So back to our tutorial. The next step is I want to make it so, well, so it doesn't do that. But basically I'm going to change the form model. So instead of having just text fields, you can see it back here. We'll have actually like check boxes. So right now they're just text fields. I want to change those to like iOS toggles. So if I go back to the tutorial here, the first thing I'm going to do is I need to modify the points entity edit screen and change the form models from exercise meals and alcohol from them being strings to being booleans. And just by changing that, the underlying form generator that this react native project uses will know that those should be toggles instead of input fields. So if we search for points entity edit screen, you'll see here's where everything is at. So I can change from T number to T boolean. And then there's a few other changes you need to make in order to convert from a number basically to a boolean. So down and change entity to form value. So this is when it comes from the entity, when it comes from the API. It's going to present it on the UI. We're going to want to look and say, hey, if that value is equal to one, then go ahead and set it to true. And then same thing when you're converting from the form back to the entity, do the same thing if it's true or false, convert it to one or zero just because that's what I want to store in the database because the ones and the zeros allow me to add up how many points they got in a week rather than just going through true and false. So there we are. And then the last thing I want to do is actually go up into the default settings, the default form, and change the value from not just having a default ID of null, but to having default values that make sense. A null ID, the current date, true for exercise meals and alcohol, meaning that, hey, I expect you have a good day by default and only check the ones that you know you didn't succeed at. And now we should be able to refresh our app. We can go look at our entities. And if we edit it, you'll see that now they're toggled. So if we toggle this one and says I didn't exercise today, saved it, and then went back to local host 8080 and went to the points entity. You can see that it changed it. So it's changing it on both sides. All that's working. The only thing is this one's not quite the same, right? If we went and looked at this, or we edited it, it's not quite the same. So let's make that similar as well. So first of all, I'm going to start yarn because that will allow me with J-Hipster to basically just refresh the UI automatically without me having to go in and start and stop the server. And then I'm going to open up the project in IntelliJ. And then we'll find points update. And you'll see here's the HTML or the JSX or TSX for it. So we have exercise label. We have points, meals, alcohol. So we can take all those and replace them with ones that basically say true value is one, false value is zero, and it's a type checkbox. So if you're wondering how I created all that code really quickly, you'll see here I have this short call called React checkboxes. That's something I pre-recorded. I used IntelliJ's live templates feature. If you would like to use them, you can find all my live templates at this URL, github.com, slash mrable, idea live templates. And you can import them into your IntelliJ instance. And so now if I go here, go to my points and create a new one, you'll see we have checkboxes as well. So we could say, hey, for Sunday, I wasn't quite as good, but it snowed a lot. And that's why I didn't go outside. And then you can see it converted everything successfully. So the last thing or one of the last things I want to do is show you how you can configure this for octa instead of keycloak. So in the J-Hipster API, if I look in application YML, it's got a number of settings for its OAuth and OIDC configuration. So this basically talks to Spring Security and its OAuth support and gives some URIs, as well as a client ID, a client secret. And this allows its talk to keycloak and make everything work. So really the only thing we need to do is override these properties to point to a different OAuth or OIDC provider. So with octa, you can start by creating a new application. So if you don't have an account, you can go to developer.octa.com. Go ahead and click sign up and create one. I already have one. And I have my password stored in one password. So I can sign in. I can create a new application. So this will work for any J-Hipster app. I'm going to click on web. I'm going to say my Spring Boot API. And then for the login redirect URI, you're going to want to use localhost 8080 login locally. And when you deploy to production, obviously, you're going to have to add one of those for production as well. And then we'll go ahead and say refresh token. And there's a new feature in J-Hipster 5.8 that I just added that allows you to do global OIDC logout. And so to make that feature work, you actually have to go in and add a logout redirect URI of just the domain where you're hitting not the slash login. And now I have a client ID and a client secret. So what I recommend you do is create a octa.env file. So I actually already have one. I call it dot octa.env. And you can see here, it overrides all those properties for Spring Security. And we're just going to edit these two. So I can go ahead and copy this one, edit that one, client secret as well. And this is generally a good idea because you're not storing your client ID or your client secret in GitHub when you check your project. And you'll just have the regular key cloak settings in there. And so now what you can do is you can stop this process, source your octa.env, and restart it. And now this J-Hipster app will be talking to octa for authentication. And you can see, since I'm already logged in, it automatically logged me in. And like I said, there's a new feature in 5.8.0 that actually logs you out. So if you try to sign in again, it'll prompt you. And you could log in, for instance, with a different user. There we are. And so the next step is to configure the native application. So we're going to use this login redirect URI. And what happens is when you create the React Native application, it generates this for you, whatever your app name is. And so on octa, see if I'm still logged in. Nope. So I've got to log out because I'm logged in as that demo user. And then I'll log in with my admin account. And I can create a new native application. And we'll just say React Native. And log in redirect URI is this. And we'll say refresh token as well. And so then it gets a client ID. So you want to put that into a path name here. It's reactNativeAppModulesLoginLogin.sagas.js. Search for that. And it's right here, basically, in the configuration. Put that in there. And you can remove this client ID that's no longer used. And this normally gets us information from the endpoint in the API. So if you look at API.info, you can see it has an issuer in there. It actually has a client ID. But this is a client ID for the Spring Boot API. This is not for the native app. So that's why I overwrote it. And now we can restart, or we can log out of this one. So we'll go ahead and hit Logout. And then refresh, and then log back in. Now you see it's going to octa. And we can go ahead and put our credentials in. And you can see your entities. Now the reason you'll be able to see the points entities in this case is because we haven't done anything filter on the admin person. So if you want to see how to do that, check out my 21 points application. It has many security features in there that prevent users from seeing each other's data, as well as editing each other's data. The other thing I wanted to show you is Reactotron. So Reactotron is great for debugging React native application. So you can see here if I go and I refresh my app, it actually shows up here in Reactotron. So you can see that it made a request in the beginning to get my account. And you can see that it actually came back with a 200. And you can see the response. So that's all pretty neat. And it allows you to actually put in console.tron.log instead of console.log and get debug messages in there. So I found it very useful in my use of React native. If you want to package this app for production, I'm not going to go into it here today because it's already kind of long. But this shows you how to package your Spring Boot app and send it to Cloud Foundry. And then what you need to do on the client to make that work. And also, I included instructions for deploying it to Google Cloud Platform using Kubernetes. And then, of course, the clients. You just have to update to point to that URL. So that should all be all you need in there. If you have any questions, please leave a comment on this post. So you can find the source code again on GitHub. If you want to learn more about J-Hipster, go to jhipster.tech. The Ignite J-Hipster project, which I use to create this, is from John Rudell. And you can find it on GitHub as well. My name is Matt Raible. Follow me on Twitter, at mraible. Follow my team at Octadev if you like this screencast and want to see more when they're produced or when they're published. Friends don't let friends write authentication. So go to developer.oc.com and subscribe to our YouTube channel because we have lots of good stuff here in screencast like this one.