Adding Login/Registration to a Flex Mobile project

This post is more than 2 years old.

What follows is a simple experiment in adding login and registration to a Flex Mobile project. There are probably better ways of doing this but my main interest here was to see what was possible. I've done this before with Flex applications. It's not difficult at all. But Flex Mobile has a different way of handling user views. There's a push/pop system that makes it easier to direct the user throughout the application. Specifically I was curious about the tabbed navigator - one of two main views Flex Mobile applications start with - and how it could handle presenting a User/Registration view that could be swapped to the 'real' UI once finished. Again - this was just me playing around to see what was possible. Consider it a proof of concept. Also - I avoided doing "real" login/registration as you will see. Doing network calls in a Flex Mobile application is no more difficult than a traditional Flex application. If readers want to see that, I can definitely make it real. (I'd estimate it would take me longer to FTP the ColdFusion files to my server than it would to actually write the code.)

I began with a new Flex Mobile application that started off with the Tabbed view.

One of the things I really like about Flash Builder is how far it goes to help you get things done quicker. Notice in the UI above I was able to add my two tabs (Login and Registration) before I even finished creating the project. My finished application is going to need more tabs of course, but these are the two initial tabs I'll be starting off with. Once done I can immediately run my application and switch between my Login and Registration views.

Ok - so what next? Remember I said I didn't want to bother with a real login/registration process. I just needed to fake it. I decided to add a simple form with a static login process that once done would 'speak' to my parent application to begin the 'switch to normal' process. Here's the login view:

<?xml version="1.0" encoding="utf-8"?> <s:View xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" title="Login">

&lt;fx:Script&gt;
&lt;![CDATA[
import mx.core.FlexGlobals;

protected function handleLogin(event:MouseEvent):void {
	if(username.text == "user" && password.text == "password") {
		FlexGlobals.topLevelApplication.loadMain();
	} else {
		statusLabel.text = "Incorrect. (Try user/password)";
	}
}
]]&gt;
&lt;/fx:Script&gt;

&lt;s:layout&gt;
	&lt;s:VerticalLayout gap="10" paddingTop="10" paddingLeft="10" paddingRight="10" /&gt;
&lt;/s:layout&gt;

&lt;s:Label text="Username: " /&gt;
&lt;s:TextInput id="username" width="100%" /&gt;

&lt;s:Label text="Password: " /&gt;
&lt;s:TextInput id="password" displayAsPassword="true" width="100%" /&gt;

&lt;s:Button label="Login" click="handleLogin(event)" width="100%" /&gt;

&lt;s:Label id="statusLabel" color="#FF0000" fontWeight="bold" /&gt;

</s:View>

The bottom of this template is just a form. Two labels and a button. I also added a label that will be used for a status message when login fails. If you go to the top and look at the handleLogin function, you can see I've hard coded a valid username and password. The truly important line to focus in on here is this:

FlexGlobals.topLevelApplication.loadMain();

The use of FlexGlobals is something I recently discovered from another Flex Mobile application. By using FlexGlobals.topLevelApplication I get a quick and simple pointer to the top level file of my application. The registration view is even simpler. My form is a little different, but the click handler does even less.

<?xml version="1.0" encoding="utf-8"?> <s:View xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" title="Register">

&lt;fx:Script&gt;
&lt;![CDATA[
import mx.core.FlexGlobals;
		
protected function handleRegister(event:MouseEvent):void {
	//Any value for registration is ok with me...
	FlexGlobals.topLevelApplication.loadMain();
}
]]&gt;
&lt;/fx:Script&gt;

&lt;s:layout&gt;
	&lt;s:VerticalLayout gap="10" paddingTop="10" paddingLeft="10" paddingRight="10" /&gt;
&lt;/s:layout&gt;

&lt;s:Label text="Username: " /&gt;
&lt;s:TextInput id="username" width="100%" /&gt;

&lt;s:Label text="Password: " /&gt;
&lt;s:TextInput id="password" displayAsPassword="true" width="100%" /&gt;

&lt;s:Label text="Confirm Password: " /&gt;
&lt;s:TextInput id="password2" displayAsPassword="true" width="100%" /&gt;

&lt;s:Button label="Register" click="handleRegister(event)" width="100%" /&gt;

&lt;s:Label id="statusLabel" color="#FF0000" fontWeight="bold" /&gt;

</s:View>

Ok - hopefully everything so far seems pretty simple. Remember that Flash Builder set up my tabbed navigator and my views for me. I just had to add the forms and the click handlers. If we run the project now we can see both views. Here's a shot of both views.


Now for the fun part. Let's switch to the root file of my application and see what loadMain() is doing. Remember, this function is called after a user has either logged in or registered. Basically, it's where we need to switch the application's UI.

<?xml version="1.0" encoding="utf-8"?> <s:TabbedViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"> <fx:Declarations> <!-- Place non-visual elements (e.g., services, value objects) here --> </fx:Declarations>

&lt;fx:Script&gt;
&lt;![CDATA[
import views.*;

public function loadMain():void {
	trace('called');

	var vn1:ViewNavigator = new ViewNavigator();
	vn1.firstView = views.HomeView;
	vn1.label = "Home";
	vn1.percentWidth=100;

	var vn2:ViewNavigator = new ViewNavigator();
	vn2.firstView = views.Part2View;
	vn2.label = "Foo";
	vn2.percentWidth=100;

	var vn3:ViewNavigator = new ViewNavigator();
	vn3.firstView = views.Part3View;
	vn3.label = "Something";
	vn3.percentWidth=100;

	this.tabbedNavigator.removeAll();
	//Bug - credit for fix: Dynamic_Internet_Dev and thread: http://forums.adobe.com/message/3702163
	this.tabbedNavigator.validateNow();
	this.tabbedNavigator.addItem(vn1);
	this.tabbedNavigator.addItem(vn2);
	this.tabbedNavigator.addItem(vn3);
	
}
]]&gt;
&lt;/fx:Script&gt;

&lt;s:navigators&gt;
	&lt;s:ViewNavigator label="Login" firstView="views.LoginView" width="100%"/&gt;
	&lt;s:ViewNavigator label="Register" firstView="views.RegisterView" width="100%"/&gt;
&lt;/s:navigators&gt;

</s:TabbedViewNavigatorApplication>

So - what's going on here? The TabbedViewNavigator has a few APIs that allow you to change the tabs that are visible. Unfortunately I ran into multiple bugs when working with this API. Luckily there's a work around. Look at loadMain(). I begin by defining thee view navigators objects. These represent my new tabs for the "real" application. HomeView, Part2View, and Part3View were made by me creating new files in Flash Builder.

For now those views don't do anything so I won't bother posting the code here. (But everything will be available in in the download.) Once I've defined my three views, I clear the tab navigator using removeAll. Here is where a bug exists. I initially had just the three addItem's there. When run I'd get an error from within the Flex framework itself. A user (whose name I don't know - but thank you!) from the Flex forums provided the fix you see there - validateNow(). Don't ask me why it works - it just does. The main point though is that we end up with all new tabs within our application. Here's the view after logging in.

That's it. I've included the FXP if you want to play with this yourself. As always - I'm open to alternatives and better ways of doing this.

Download attached file.

Raymond Camden's Picture

About Raymond Camden

Raymond is a developer advocate for HERE Technologies. He focuses on JavaScript, serverless and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by MB posted on 5/31/2011 at 8:07 PM

the link seems to be broken to the file.

404 - File or directory not found.
The resource you are looking for might have been removed, had its name changed, or is temporarily unavailable.

Comment 2 by Raymond Camden posted on 5/31/2011 at 8:10 PM

Looks to be an IIS issue. Need to make it treat FXP as binary so it will be downloaded.

Comment 3 by Raymond Camden posted on 5/31/2011 at 8:17 PM

Try now please.

Comment 4 by MB posted on 6/1/2011 at 2:25 AM

All good..thanks!

Comment 5 by Brian Bishop posted on 9/22/2011 at 12:24 PM

Boom! this is exactly what I needed. Was previously trying to have a ViewNavigatorApplication that then switches to a TabbedNavigatorApplication - was a bit bulky

P.S. I have a demo on my blog and links to a tutorial on how to get mobile Flex apps to run in the browser... would be really cool for this sort of demo... let me know if you get it up and running:)

Comment 6 by vinod posted on 2/3/2012 at 11:49 AM

Thanks working good .
Is this possible to use the sqlite for storing username and password.

Comment 7 by Raymond Camden posted on 2/3/2012 at 4:57 PM

Sure.

Comment 8 by Matt posted on 4/15/2012 at 4:28 PM

Hi Raymond, I found your post very useful but I'm still facing a problem that I can't seem to resolve and maybe you could help me with it (I've been programing on FB for only two months and I'm still on a learning stage).

In your code for username verification, you showed us this:

09 protected function handleLogin(event:MouseEvent):void {
10 if(username.text == "user" && password.text == "password") {
11 FlexGlobals.topLevelApplication.loadMain();
12 } else {
13 statusLabel.text = "Incorrect. (Try user/password)";

Now, I believe that if I type "user" as my username and "password" as the password, the app would allow me to go to the next stage.

Having said that, my main issue comes when I create new users in the registration view. I've created a db using SQLite where I store Users/Passwords but I can't seem to find a validation method so that new users/passwords could function next time I try to login to the app.

Would you mind helping me with that or at least share any link where this problem is solved? I've been surfing the web for over an hour now and I can't seem to find what I'm looking for.

Thanks a lot!
Matt

Comment 9 by Raymond Camden posted on 4/16/2012 at 12:26 AM

The main thing would be to change line 10 above to a SQL call that takes in the input and sees if it matches a row in the table. Does that make sense?

Comment 10 by PhamHuyAnh posted on 4/28/2012 at 9:54 PM

Perfect sample!!
You rock!!

Comment 11 by Jeremy Keczan posted on 9/5/2012 at 9:34 PM

After working with Flex Mobile for the past year I find the best practice is to avoid Flex Globals because it severely limits the reuse of code.

The easiest way in my opinion is to completely incapsulate the login as a component and simple create a LoginComponentEvent to pass events from the login into something else.

I usually does this with VGroups if the login will be put in a view or use an actual view if the login is meant to stand alone.

Just my two cents

Comment 12 by Yogesh posted on 9/6/2012 at 9:37 PM

Hey m very new.. i have used this code bt it throwing exception..

ReferenceError: Error #1069: Property loadMain not found on LoginRegister and there is no default value.
at views::LoginView/handleLogin()[D:\Work\LoginRegister\flex_src\views\LoginView.mxml:11]
at views::LoginView/___LoginView_Button1_click()[D:\Work\LoginRegister\flex_src\views\LoginView.mxml:29]

hey plz tell me how can i remove this..m nt a professional developer but want to develop an app in flex. this is my very first try.. so plz help me ..Thank you.

Comment 13 by Jeremy Keczan posted on 9/11/2012 at 7:47 PM

It looks like either the function is private in your code, can you post the file you are using?

Comment 14 by Yogesh posted on 9/12/2012 at 3:42 PM

Oh sry sir I loss the code..
Sir will u guide me about developing a mobile application in flex 4.6.?

Comment 15 by Jeremy Keczan posted on 9/12/2012 at 6:01 PM

I can not guide you personally but there is some really good tutorials out there and the adobe evangelicals do a create job of posting updates on their blogs about flex 4.6. I would advise starting there .

Comment 16 by Danny posted on 9/12/2013 at 6:55 PM

how to login out after being load to main application.. pls help tq

Comment 17 by xiangrumei posted on 6/25/2014 at 8:42 AM

when i add icon to vn1, var vn1:ViewNavigator = new ViewNavigator(); like this
vn1.icon = "@Embed('assets/pageimg/my.png')"; it isn't work, can you tell me why. how can i do.

Comment 18 by Raymond Camden posted on 6/25/2014 at 6:03 PM

Sorry, I haven't used Flex Mobile in over 2 years.

Comment 19 by Vijay posted on 7/14/2014 at 10:48 AM

Is there a way to keep Flex Mobile Application logged in always as of gmail and other mobile applications do, on smartphones. It should ask for login only once and stay logged in even if i don't use application for long, unless i personally logout

Comment 20 by Raymond Camden posted on 7/14/2014 at 5:52 PM

You could cache the authentication values locally, but that could be insecure. You could issue a token from the server that is timed, ie, if the remote device passes the token, it auto logs in but the token only works for 7-14 days.

Comment 21 (In reply to #18) by Andy posted on 2/20/2015 at 3:32 AM

Hey Raymond,
Found this tip on switching tabs really useful, thanks for that. I felt compelled to say thanks, specially when I read that you havent used Flex Mobile in over 2 years. That made me a bit sad ;-) What do you use instead these days? I left for a while too, but came back to Apache Flex 4.14 recently, and am liking the way Flex works again.

Comment 22 (In reply to #18) by Andy posted on 2/20/2015 at 3:33 AM

By the way, you helped me a fair bit back in the day. Adobe Evangelists were omnipresent in Google, and you and Devgirl always had the answers! Happy days...

Comment 23 (In reply to #22) by Raymond Camden posted on 2/20/2015 at 3:39 AM

Glad to have been helpful. :)

Comment 24 (In reply to #21) by Raymond Camden posted on 2/20/2015 at 3:40 AM

I use Cordova pretty much exclusively. :)