SlideShare a Scribd company logo
1 of 14
Download to read offline
Creating an Uber Clone - Part XIII
Now that we have a server and a mock client we need to connect them together so we’ll have a working prototype. We also need to implement some core functionality
such as SMS Activation
Twilio & WebSocket Setup
✦We need to use the Extension Manager to install
websocket support
✦Signup to Twilio
✦You will need the following values from the Twilio
developer account: Account SID, Auth Token & Phone
Number
© Codename One 2017 all rights reserved
Before we get started we need to add some things to the client project. First we need to add the Web Sockets cn1lib from the extension manager. This is pretty simple to
do if you already added a cn1lib before.

Next we need to signup to twilio.com as developers. They have a free trial account. Notice we don’t need to install support for the Twilio lib since we already installed the
SMS Activation cn1lib before. Notice that we are sending the SMS activation code from the client side. This is a bad practice. You should use the server Twilio API and
send the SMS activation code from there.

I chose to use this approach because it's seamless and shows the usage of API's on the client which is what I'm trying to teach. However, keeping authentication code
on the server is far more secure.

You will need the following values from the Twilio developer account: Account SID, Auth Token & Phone Number. Make sure to pick a US phone number for the free
account otherwise payment would be required.
public class Globals {
public static final String SERVER_URL = "http://localhost:8080/";
public static final String SERVER_SOCKET_URL = "ws://localhost:8080/wsMsg";
public static final String TWILIO_ACCOUNT_SID = "AC....";
public static final String TWILIO_AUTH_TOKEN = "1d....";
public static final String TWILIO_FROM_PHONE = "+14.....";
}
Globals
Once you have those values you can create a new Globals class which we will use for the global application data.

Notice that you might want to replace localhost with your IP during development so you can test a device against a server running on your machine. The device would
obviously need to be connected to the same wifi
public class Globals {
public static final String SERVER_URL = "http://localhost:8080/";
public static final String SERVER_SOCKET_URL = "ws://localhost:8080/wsMsg";
public static final String TWILIO_ACCOUNT_SID = "AC....";
public static final String TWILIO_AUTH_TOKEN = "1d....";
public static final String TWILIO_FROM_PHONE = "+14.....";
}
Globals
The following values are the values we have from Twilio. For convenience I use static import for these constants within the code
public class User implements PropertyBusinessObject {
public final LongProperty<User> id = new LongProperty<>("id");
public final Property<String, User> givenName = new Property<>("givenName");
public final Property<String, User> surname = new Property<>("surname");
public final Property<String, User> phone = new Property<>("phone");
public final Property<String, User> email = new Property<>("email");
public final Property<String, User> facebookId = new Property<>("facebookId");
public final Property<String, User> googleId = new Property<>("googleId");
public final BooleanProperty<User> driver = new BooleanProperty<>("driver");
public final Property<String, User> car = new Property<>("givenName");
public final FloatProperty<User> currentRating = new FloatProperty<>("currentRating");
public final DoubleProperty<User> latitude = new DoubleProperty<>("latitude");
public final DoubleProperty<User> longitude = new DoubleProperty<>("longitude");
public final FloatProperty<User> direction = new FloatProperty<>("direction");
public final Property<String, User> authToken = new Property<>("authToken");
public final Property<String, User> password = new Property<>("password");
private final PropertyIndex idx = new PropertyIndex(this, "User", id, givenName,
surname, phone, email, facebookId, googleId, driver, car, currentRating,
latitude, longitude, direction, authToken, password);
@Override
public PropertyIndex getPropertyIndex() {
return idx;
}
}
User (Client Side)
The User class on the client side mirrors the UserDAO but uses the Properties syntax so we can leverage observability, JSON, persistence and other cool capabilities. If
you are familiar with properties already you won’t notice anything special about this class it’s just a standard property object. If you aren’t familiar with properties please
check out the video covering them as it would be helpful moving forward.
public class UserService {
private static User me;
public static void loadUser() {
me = new User();
PreferencesObject.create(me).bind();
}
public static void logout() {
Preferences.set("token", null);
}
public static boolean isLoggedIn() {
return Preferences.get("token", null) != null;
}
public static void sendSMSActivationCode(String phoneNumber) {
TwilioSMS tw = TwilioSMS.create(TWILIO_ACCOUNT_SID,
TWILIO_AUTH_TOKEN, TWILIO_FROM_PHONE);
Random r = new Random();
String val = "";
for(int iter = 0 ; iter < 4 ; iter++) {
val += r.nextInt(10);
}
Preferences.set("phoneVerification", val);
tw.sendSmsAsync(phoneNumber, val);
}
UserService (Client Side)
We need to define a connection layer that will abstract the server access code. This will allow us flexibility as we modify the server implementation and the client
implementation. It will also make testing far easier by separating the different pieces into tiers.

The abstraction is similar to the one we have in the server. I chose to go with a mostly static class implementation for the user service as it's inherently a static web
service. It makes no sense to have more than one UserService.

Once logged in we will cache the current user object here so we have all the data locally and don't need server communication for every query
public class UserService {
private static User me;
public static void loadUser() {
me = new User();
PreferencesObject.create(me).bind();
}
public static void logout() {
Preferences.set("token", null);
}
public static boolean isLoggedIn() {
return Preferences.get("token", null) != null;
}
public static void sendSMSActivationCode(String phoneNumber) {
TwilioSMS tw = TwilioSMS.create(TWILIO_ACCOUNT_SID,
TWILIO_AUTH_TOKEN, TWILIO_FROM_PHONE);
Random r = new Random();
String val = "";
for(int iter = 0 ; iter < 4 ; iter++) {
val += r.nextInt(10);
}
Preferences.set("phoneVerification", val);
tw.sendSmsAsync(phoneNumber, val);
}
UserService (Client Side)
We bind the user object to preferences so changes to the user object implicitly connect to the Preferences storage API and visa versa. Preferences allow us to store keys
and values in storage which maps every entry to a similar key/value pair
public class UserService {
private static User me;
public static void loadUser() {
me = new User();
PreferencesObject.create(me).bind();
}
public static void logout() {
Preferences.set("token", null);
}
public static boolean isLoggedIn() {
return Preferences.get("token", null) != null;
}
public static void sendSMSActivationCode(String phoneNumber) {
TwilioSMS tw = TwilioSMS.create(TWILIO_ACCOUNT_SID,
TWILIO_AUTH_TOKEN, TWILIO_FROM_PHONE);
Random r = new Random();
String val = "";
for(int iter = 0 ; iter < 4 ; iter++) {
val += r.nextInt(10);
}
Preferences.set("phoneVerification", val);
tw.sendSmsAsync(phoneNumber, val);
}
UserService (Client Side)
Whether we are logged in or out is determined by the token value. We need that to send updates to the server side
public class UserService {
private static User me;
public static void loadUser() {
me = new User();
PreferencesObject.create(me).bind();
}
public static void logout() {
Preferences.set("token", null);
}
public static boolean isLoggedIn() {
return Preferences.get("token", null) != null;
}
public static void sendSMSActivationCode(String phoneNumber) {
TwilioSMS tw = TwilioSMS.create(TWILIO_ACCOUNT_SID,
TWILIO_AUTH_TOKEN, TWILIO_FROM_PHONE);
Random r = new Random();
String val = "";
for(int iter = 0 ; iter < 4 ; iter++) {
val += r.nextInt(10);
}
Preferences.set("phoneVerification", val);
tw.sendSmsAsync(phoneNumber, val);
}
UserService (Client Side)
I'm creating the 4 digit verification code and sending it via the Twilio SMS webservice API. I'm also storing the value in Preferences so I can check against it when it's
received even if the app dies for some reason
Preferences.set("phoneVerification", val);
tw.sendSmsAsync(phoneNumber, val);
}
public static void resendSMSActivationCode(String phoneNumber) {
TwilioSMS tw = TwilioSMS.create(TWILIO_ACCOUNT_SID,
TWILIO_AUTH_TOKEN, TWILIO_FROM_PHONE);
tw.sendSmsAsync(phoneNumber,
Preferences.get("phoneVerification", null));
}
public static boolean validateSMSActivationCode(String code) {
String val = Preferences.get("phoneVerification", null);
return code.indexOf(val) > -1 && code.length() < 80;
}
public static boolean userExists(String phoneNumber) {
Response<byte[]> b = Rest.get(SERVER_URL + "user/exists").
acceptJson().
queryParam("phone", phoneNumber).getAsBytes();
if(b.getResponseCode() == 200) {
// the t from true
return b.getResponseData()[0] == (byte)'t';
}
return false;
}
UserService (Client Side)
This method is invoked to validate the received SMS code, notice I don't just use equals since the validation string might include the full SMS text. This can happen on
Android where we can automatically validate. Notice I still limit the length of the string to prevent an attack where a user can inject all the possible 4 code combinations
into this method
Preferences.set("phoneVerification", val);
tw.sendSmsAsync(phoneNumber, val);
}
public static void resendSMSActivationCode(String phoneNumber) {
TwilioSMS tw = TwilioSMS.create(TWILIO_ACCOUNT_SID,
TWILIO_AUTH_TOKEN, TWILIO_FROM_PHONE);
tw.sendSmsAsync(phoneNumber,
Preferences.get("phoneVerification", null));
}
public static boolean validateSMSActivationCode(String code) {
String val = Preferences.get("phoneVerification", null);
return code.indexOf(val) > -1 && code.length() < 80;
}
public static boolean userExists(String phoneNumber) {
Response<byte[]> b = Rest.get(SERVER_URL + "user/exists").
acceptJson().
queryParam("phone", phoneNumber).getAsBytes();
if(b.getResponseCode() == 200) {
// the t from true
return b.getResponseData()[0] == (byte)'t';
}
return false;
}
UserService (Client Side)
Maps to the user exists method in the server which we use to determine add/login flows. I use the Rest API to make a single connection with the get method. In this case
the response is the string true or the string false so I can just check against the letter t
// the t from true
return b.getResponseData()[0] == (byte)'t';
}
return false;
}
public static boolean addNewUser(User u) {
Response<String> token = Rest.post(SERVER_URL + "user/add").
jsonContent().
body(u.getPropertyIndex().toJSON()).getAsString();
if(token.getResponseCode() != 200) {
return false;
}
Preferences.set("token", token.getResponseData());
return true;
}
public static void loginWithPhone(String phoneNumber,
String password, final SuccessCallback<User> onSuccess,
final FailureCallback<Object> onError) {
Rest.get(SERVER_URL + "user/login").
acceptJson().
queryParam("password", password).
queryParam("phone", phoneNumber).
getAsJsonMapAsync(new Callback<Response<Map>>() {
UserService (Client Side)
When adding a user I use the Rest API's post method. Here I can set the body to the JSON content of the User object. The response is a String token representing the
user which we can now store into `Preferences
public static void loginWithPhone(String phoneNumber,
String password, final SuccessCallback<User> onSuccess,
final FailureCallback<Object> onError) {
Rest.get(SERVER_URL + "user/login").
acceptJson().
queryParam("password", password).
queryParam("phone", phoneNumber).
getAsJsonMapAsync(new Callback<Response<Map>>() {
@Override
public void onSucess(Response<Map> value) {
me = new User();
me.getPropertyIndex().populateFromMap(
value.getResponseData());
Preferences.set("token", me.authToken.get());
PreferencesObject.create(me).bind();
onSuccess.onSucess(me);
}
@Override
public void onError(Object sender, Throwable err,
int errorCode, String errorMessage) {
onError.onError(null, err, errorCode, errorMessage);
}
});
UserService (Client Side)
The login method accepts a phone and password and is invoked after we validated the phone. It can succeed or fail.
public static void loginWithPhone(String phoneNumber,
String password, final SuccessCallback<User> onSuccess,
final FailureCallback<Object> onError) {
Rest.get(SERVER_URL + "user/login").
acceptJson().
queryParam("password", password).
queryParam("phone", phoneNumber).
getAsJsonMapAsync(new Callback<Response<Map>>() {
@Override
public void onSucess(Response<Map> value) {
me = new User();
me.getPropertyIndex().populateFromMap(
value.getResponseData());
Preferences.set("token", me.authToken.get());
PreferencesObject.create(me).bind();
onSuccess.onSucess(me);
}
@Override
public void onError(Object sender, Throwable err,
int errorCode, String errorMessage) {
onError.onError(null, err, errorCode, errorMessage);
}
});
UserService (Client Side)
If we get back a token that means the UserAuthenticationException wasn't thrown in the server and we can set it into the Preferences otherwise we need to send a failure
callback

More Related Content

Similar to Creating an Uber Clone - Part XIII: Twilio & WebSocket Setup

Building Your First App with MongoDB Stitch
Building Your First App with MongoDB StitchBuilding Your First App with MongoDB Stitch
Building Your First App with MongoDB StitchMongoDB
 
How React Native, Appium and me made each other shine @ContinuousDeliveryAmst...
How React Native, Appium and me made each other shine @ContinuousDeliveryAmst...How React Native, Appium and me made each other shine @ContinuousDeliveryAmst...
How React Native, Appium and me made each other shine @ContinuousDeliveryAmst...Wim Selles
 
CloudBrew: Windows Azure Mobile Services - Next stage
CloudBrew: Windows Azure Mobile Services - Next stageCloudBrew: Windows Azure Mobile Services - Next stage
CloudBrew: Windows Azure Mobile Services - Next stageTeemu Tapanila
 
Creating a Whatsapp Clone - Part XIII.pdf
Creating a Whatsapp Clone - Part XIII.pdfCreating a Whatsapp Clone - Part XIII.pdf
Creating a Whatsapp Clone - Part XIII.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdfCreating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdfShaiAlmog1
 
“Create your own cryptocurrency in an hour” - Sandip Pandey
“Create your own cryptocurrency in an hour” - Sandip Pandey“Create your own cryptocurrency in an hour” - Sandip Pandey
“Create your own cryptocurrency in an hour” - Sandip PandeyEIT Digital Alumni
 
Creating a Facebook Clone - Part XLV - Transcript.pdf
Creating a Facebook Clone - Part XLV - Transcript.pdfCreating a Facebook Clone - Part XLV - Transcript.pdf
Creating a Facebook Clone - Part XLV - Transcript.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part XI - Transcript.pdf
Creating a Whatsapp Clone - Part XI - Transcript.pdfCreating a Whatsapp Clone - Part XI - Transcript.pdf
Creating a Whatsapp Clone - Part XI - Transcript.pdfShaiAlmog1
 
Tutorial: Building Your First App with MongoDB Stitch
Tutorial: Building Your First App with MongoDB StitchTutorial: Building Your First App with MongoDB Stitch
Tutorial: Building Your First App with MongoDB StitchMongoDB
 
How to build twitter bot using golang from scratch
How to build twitter bot using golang from scratchHow to build twitter bot using golang from scratch
How to build twitter bot using golang from scratchKaty Slemon
 
Integrating Security Roles into Microsoft Silverlight Applications
Integrating Security Roles into Microsoft Silverlight ApplicationsIntegrating Security Roles into Microsoft Silverlight Applications
Integrating Security Roles into Microsoft Silverlight ApplicationsDan Wahlin
 
AI: Mobile Apps That Understands Your Intention When You Typed
AI: Mobile Apps That Understands Your Intention When You TypedAI: Mobile Apps That Understands Your Intention When You Typed
AI: Mobile Apps That Understands Your Intention When You TypedMarvin Heng
 
Google Web Toolkits
Google Web ToolkitsGoogle Web Toolkits
Google Web ToolkitsYiguang Hu
 
Hi, I need some one to help me with Design a client-server Chat so.pdf
Hi, I need some one to help me with Design a client-server Chat so.pdfHi, I need some one to help me with Design a client-server Chat so.pdf
Hi, I need some one to help me with Design a client-server Chat so.pdffashiongallery1
 

Similar to Creating an Uber Clone - Part XIII: Twilio & WebSocket Setup (20)

Id32
Id32Id32
Id32
 
Building Your First App with MongoDB Stitch
Building Your First App with MongoDB StitchBuilding Your First App with MongoDB Stitch
Building Your First App with MongoDB Stitch
 
How React Native, Appium and me made each other shine @ContinuousDeliveryAmst...
How React Native, Appium and me made each other shine @ContinuousDeliveryAmst...How React Native, Appium and me made each other shine @ContinuousDeliveryAmst...
How React Native, Appium and me made each other shine @ContinuousDeliveryAmst...
 
CloudBrew: Windows Azure Mobile Services - Next stage
CloudBrew: Windows Azure Mobile Services - Next stageCloudBrew: Windows Azure Mobile Services - Next stage
CloudBrew: Windows Azure Mobile Services - Next stage
 
Creating a Whatsapp Clone - Part XIII.pdf
Creating a Whatsapp Clone - Part XIII.pdfCreating a Whatsapp Clone - Part XIII.pdf
Creating a Whatsapp Clone - Part XIII.pdf
 
Creating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdfCreating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdf
 
Hexagonal architecture
Hexagonal architectureHexagonal architecture
Hexagonal architecture
 
“Create your own cryptocurrency in an hour” - Sandip Pandey
“Create your own cryptocurrency in an hour” - Sandip Pandey“Create your own cryptocurrency in an hour” - Sandip Pandey
“Create your own cryptocurrency in an hour” - Sandip Pandey
 
Creating a Facebook Clone - Part XLV - Transcript.pdf
Creating a Facebook Clone - Part XLV - Transcript.pdfCreating a Facebook Clone - Part XLV - Transcript.pdf
Creating a Facebook Clone - Part XLV - Transcript.pdf
 
Creating a Whatsapp Clone - Part XI - Transcript.pdf
Creating a Whatsapp Clone - Part XI - Transcript.pdfCreating a Whatsapp Clone - Part XI - Transcript.pdf
Creating a Whatsapp Clone - Part XI - Transcript.pdf
 
Capstone ms2
Capstone ms2Capstone ms2
Capstone ms2
 
Bot builder v4 HOL
Bot builder v4 HOLBot builder v4 HOL
Bot builder v4 HOL
 
WCF Fundamentals
WCF Fundamentals WCF Fundamentals
WCF Fundamentals
 
Tutorial: Building Your First App with MongoDB Stitch
Tutorial: Building Your First App with MongoDB StitchTutorial: Building Your First App with MongoDB Stitch
Tutorial: Building Your First App with MongoDB Stitch
 
How to build twitter bot using golang from scratch
How to build twitter bot using golang from scratchHow to build twitter bot using golang from scratch
How to build twitter bot using golang from scratch
 
Integrating Security Roles into Microsoft Silverlight Applications
Integrating Security Roles into Microsoft Silverlight ApplicationsIntegrating Security Roles into Microsoft Silverlight Applications
Integrating Security Roles into Microsoft Silverlight Applications
 
AI: Mobile Apps That Understands Your Intention When You Typed
AI: Mobile Apps That Understands Your Intention When You TypedAI: Mobile Apps That Understands Your Intention When You Typed
AI: Mobile Apps That Understands Your Intention When You Typed
 
Google Web Toolkits
Google Web ToolkitsGoogle Web Toolkits
Google Web Toolkits
 
ELEVATE Paris
ELEVATE ParisELEVATE Paris
ELEVATE Paris
 
Hi, I need some one to help me with Design a client-server Chat so.pdf
Hi, I need some one to help me with Design a client-server Chat so.pdfHi, I need some one to help me with Design a client-server Chat so.pdf
Hi, I need some one to help me with Design a client-server Chat so.pdf
 

More from ShaiAlmog1

The Duck Teaches Learn to debug from the masters. Local to production- kill ...
The Duck Teaches  Learn to debug from the masters. Local to production- kill ...The Duck Teaches  Learn to debug from the masters. Local to production- kill ...
The Duck Teaches Learn to debug from the masters. Local to production- kill ...ShaiAlmog1
 
create-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdfcreate-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdfShaiAlmog1
 
create-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdfcreate-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdfShaiAlmog1
 
create-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdfcreate-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdfShaiAlmog1
 
create-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdfcreate-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdfShaiAlmog1
 
create-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdfcreate-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdfShaiAlmog1
 
create-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdfcreate-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdfShaiAlmog1
 
create-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdfcreate-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdfShaiAlmog1
 
create-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdfcreate-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdfShaiAlmog1
 
create-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdfcreate-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdfShaiAlmog1
 
create-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdfcreate-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdfShaiAlmog1
 
create-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdfcreate-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdfShaiAlmog1
 
create-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdfcreate-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdfCreating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdfCreating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdfCreating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdfCreating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part IV.pdfCreating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part IV.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdfCreating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part IX.pdf
Creating a Whatsapp Clone - Part IX.pdfCreating a Whatsapp Clone - Part IX.pdf
Creating a Whatsapp Clone - Part IX.pdfShaiAlmog1
 

More from ShaiAlmog1 (20)

The Duck Teaches Learn to debug from the masters. Local to production- kill ...
The Duck Teaches  Learn to debug from the masters. Local to production- kill ...The Duck Teaches  Learn to debug from the masters. Local to production- kill ...
The Duck Teaches Learn to debug from the masters. Local to production- kill ...
 
create-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdfcreate-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdf
 
create-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdfcreate-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdf
 
create-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdfcreate-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdf
 
create-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdfcreate-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdf
 
create-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdfcreate-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdf
 
create-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdfcreate-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdf
 
create-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdfcreate-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdf
 
create-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdfcreate-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdf
 
create-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdfcreate-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdf
 
create-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdfcreate-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdf
 
create-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdfcreate-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdf
 
create-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdfcreate-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdf
 
Creating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdfCreating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdf
 
Creating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdfCreating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdf
 
Creating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdfCreating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdf
 
Creating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdfCreating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdf
 
Creating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part IV.pdfCreating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part IV.pdf
 
Creating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdfCreating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdf
 
Creating a Whatsapp Clone - Part IX.pdf
Creating a Whatsapp Clone - Part IX.pdfCreating a Whatsapp Clone - Part IX.pdf
Creating a Whatsapp Clone - Part IX.pdf
 

Recently uploaded

The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?XfilesPro
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 

Recently uploaded (20)

The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 

Creating an Uber Clone - Part XIII: Twilio & WebSocket Setup

  • 1. Creating an Uber Clone - Part XIII Now that we have a server and a mock client we need to connect them together so we’ll have a working prototype. We also need to implement some core functionality such as SMS Activation
  • 2. Twilio & WebSocket Setup ✦We need to use the Extension Manager to install websocket support ✦Signup to Twilio ✦You will need the following values from the Twilio developer account: Account SID, Auth Token & Phone Number © Codename One 2017 all rights reserved Before we get started we need to add some things to the client project. First we need to add the Web Sockets cn1lib from the extension manager. This is pretty simple to do if you already added a cn1lib before. Next we need to signup to twilio.com as developers. They have a free trial account. Notice we don’t need to install support for the Twilio lib since we already installed the SMS Activation cn1lib before. Notice that we are sending the SMS activation code from the client side. This is a bad practice. You should use the server Twilio API and send the SMS activation code from there. I chose to use this approach because it's seamless and shows the usage of API's on the client which is what I'm trying to teach. However, keeping authentication code on the server is far more secure. You will need the following values from the Twilio developer account: Account SID, Auth Token & Phone Number. Make sure to pick a US phone number for the free account otherwise payment would be required.
  • 3. public class Globals { public static final String SERVER_URL = "http://localhost:8080/"; public static final String SERVER_SOCKET_URL = "ws://localhost:8080/wsMsg"; public static final String TWILIO_ACCOUNT_SID = "AC...."; public static final String TWILIO_AUTH_TOKEN = "1d...."; public static final String TWILIO_FROM_PHONE = "+14....."; } Globals Once you have those values you can create a new Globals class which we will use for the global application data. Notice that you might want to replace localhost with your IP during development so you can test a device against a server running on your machine. The device would obviously need to be connected to the same wifi
  • 4. public class Globals { public static final String SERVER_URL = "http://localhost:8080/"; public static final String SERVER_SOCKET_URL = "ws://localhost:8080/wsMsg"; public static final String TWILIO_ACCOUNT_SID = "AC...."; public static final String TWILIO_AUTH_TOKEN = "1d...."; public static final String TWILIO_FROM_PHONE = "+14....."; } Globals The following values are the values we have from Twilio. For convenience I use static import for these constants within the code
  • 5. public class User implements PropertyBusinessObject { public final LongProperty<User> id = new LongProperty<>("id"); public final Property<String, User> givenName = new Property<>("givenName"); public final Property<String, User> surname = new Property<>("surname"); public final Property<String, User> phone = new Property<>("phone"); public final Property<String, User> email = new Property<>("email"); public final Property<String, User> facebookId = new Property<>("facebookId"); public final Property<String, User> googleId = new Property<>("googleId"); public final BooleanProperty<User> driver = new BooleanProperty<>("driver"); public final Property<String, User> car = new Property<>("givenName"); public final FloatProperty<User> currentRating = new FloatProperty<>("currentRating"); public final DoubleProperty<User> latitude = new DoubleProperty<>("latitude"); public final DoubleProperty<User> longitude = new DoubleProperty<>("longitude"); public final FloatProperty<User> direction = new FloatProperty<>("direction"); public final Property<String, User> authToken = new Property<>("authToken"); public final Property<String, User> password = new Property<>("password"); private final PropertyIndex idx = new PropertyIndex(this, "User", id, givenName, surname, phone, email, facebookId, googleId, driver, car, currentRating, latitude, longitude, direction, authToken, password); @Override public PropertyIndex getPropertyIndex() { return idx; } } User (Client Side) The User class on the client side mirrors the UserDAO but uses the Properties syntax so we can leverage observability, JSON, persistence and other cool capabilities. If you are familiar with properties already you won’t notice anything special about this class it’s just a standard property object. If you aren’t familiar with properties please check out the video covering them as it would be helpful moving forward.
  • 6. public class UserService { private static User me; public static void loadUser() { me = new User(); PreferencesObject.create(me).bind(); } public static void logout() { Preferences.set("token", null); } public static boolean isLoggedIn() { return Preferences.get("token", null) != null; } public static void sendSMSActivationCode(String phoneNumber) { TwilioSMS tw = TwilioSMS.create(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_FROM_PHONE); Random r = new Random(); String val = ""; for(int iter = 0 ; iter < 4 ; iter++) { val += r.nextInt(10); } Preferences.set("phoneVerification", val); tw.sendSmsAsync(phoneNumber, val); } UserService (Client Side) We need to define a connection layer that will abstract the server access code. This will allow us flexibility as we modify the server implementation and the client implementation. It will also make testing far easier by separating the different pieces into tiers. The abstraction is similar to the one we have in the server. I chose to go with a mostly static class implementation for the user service as it's inherently a static web service. It makes no sense to have more than one UserService. Once logged in we will cache the current user object here so we have all the data locally and don't need server communication for every query
  • 7. public class UserService { private static User me; public static void loadUser() { me = new User(); PreferencesObject.create(me).bind(); } public static void logout() { Preferences.set("token", null); } public static boolean isLoggedIn() { return Preferences.get("token", null) != null; } public static void sendSMSActivationCode(String phoneNumber) { TwilioSMS tw = TwilioSMS.create(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_FROM_PHONE); Random r = new Random(); String val = ""; for(int iter = 0 ; iter < 4 ; iter++) { val += r.nextInt(10); } Preferences.set("phoneVerification", val); tw.sendSmsAsync(phoneNumber, val); } UserService (Client Side) We bind the user object to preferences so changes to the user object implicitly connect to the Preferences storage API and visa versa. Preferences allow us to store keys and values in storage which maps every entry to a similar key/value pair
  • 8. public class UserService { private static User me; public static void loadUser() { me = new User(); PreferencesObject.create(me).bind(); } public static void logout() { Preferences.set("token", null); } public static boolean isLoggedIn() { return Preferences.get("token", null) != null; } public static void sendSMSActivationCode(String phoneNumber) { TwilioSMS tw = TwilioSMS.create(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_FROM_PHONE); Random r = new Random(); String val = ""; for(int iter = 0 ; iter < 4 ; iter++) { val += r.nextInt(10); } Preferences.set("phoneVerification", val); tw.sendSmsAsync(phoneNumber, val); } UserService (Client Side) Whether we are logged in or out is determined by the token value. We need that to send updates to the server side
  • 9. public class UserService { private static User me; public static void loadUser() { me = new User(); PreferencesObject.create(me).bind(); } public static void logout() { Preferences.set("token", null); } public static boolean isLoggedIn() { return Preferences.get("token", null) != null; } public static void sendSMSActivationCode(String phoneNumber) { TwilioSMS tw = TwilioSMS.create(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_FROM_PHONE); Random r = new Random(); String val = ""; for(int iter = 0 ; iter < 4 ; iter++) { val += r.nextInt(10); } Preferences.set("phoneVerification", val); tw.sendSmsAsync(phoneNumber, val); } UserService (Client Side) I'm creating the 4 digit verification code and sending it via the Twilio SMS webservice API. I'm also storing the value in Preferences so I can check against it when it's received even if the app dies for some reason
  • 10. Preferences.set("phoneVerification", val); tw.sendSmsAsync(phoneNumber, val); } public static void resendSMSActivationCode(String phoneNumber) { TwilioSMS tw = TwilioSMS.create(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_FROM_PHONE); tw.sendSmsAsync(phoneNumber, Preferences.get("phoneVerification", null)); } public static boolean validateSMSActivationCode(String code) { String val = Preferences.get("phoneVerification", null); return code.indexOf(val) > -1 && code.length() < 80; } public static boolean userExists(String phoneNumber) { Response<byte[]> b = Rest.get(SERVER_URL + "user/exists"). acceptJson(). queryParam("phone", phoneNumber).getAsBytes(); if(b.getResponseCode() == 200) { // the t from true return b.getResponseData()[0] == (byte)'t'; } return false; } UserService (Client Side) This method is invoked to validate the received SMS code, notice I don't just use equals since the validation string might include the full SMS text. This can happen on Android where we can automatically validate. Notice I still limit the length of the string to prevent an attack where a user can inject all the possible 4 code combinations into this method
  • 11. Preferences.set("phoneVerification", val); tw.sendSmsAsync(phoneNumber, val); } public static void resendSMSActivationCode(String phoneNumber) { TwilioSMS tw = TwilioSMS.create(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_FROM_PHONE); tw.sendSmsAsync(phoneNumber, Preferences.get("phoneVerification", null)); } public static boolean validateSMSActivationCode(String code) { String val = Preferences.get("phoneVerification", null); return code.indexOf(val) > -1 && code.length() < 80; } public static boolean userExists(String phoneNumber) { Response<byte[]> b = Rest.get(SERVER_URL + "user/exists"). acceptJson(). queryParam("phone", phoneNumber).getAsBytes(); if(b.getResponseCode() == 200) { // the t from true return b.getResponseData()[0] == (byte)'t'; } return false; } UserService (Client Side) Maps to the user exists method in the server which we use to determine add/login flows. I use the Rest API to make a single connection with the get method. In this case the response is the string true or the string false so I can just check against the letter t
  • 12. // the t from true return b.getResponseData()[0] == (byte)'t'; } return false; } public static boolean addNewUser(User u) { Response<String> token = Rest.post(SERVER_URL + "user/add"). jsonContent(). body(u.getPropertyIndex().toJSON()).getAsString(); if(token.getResponseCode() != 200) { return false; } Preferences.set("token", token.getResponseData()); return true; } public static void loginWithPhone(String phoneNumber, String password, final SuccessCallback<User> onSuccess, final FailureCallback<Object> onError) { Rest.get(SERVER_URL + "user/login"). acceptJson(). queryParam("password", password). queryParam("phone", phoneNumber). getAsJsonMapAsync(new Callback<Response<Map>>() { UserService (Client Side) When adding a user I use the Rest API's post method. Here I can set the body to the JSON content of the User object. The response is a String token representing the user which we can now store into `Preferences
  • 13. public static void loginWithPhone(String phoneNumber, String password, final SuccessCallback<User> onSuccess, final FailureCallback<Object> onError) { Rest.get(SERVER_URL + "user/login"). acceptJson(). queryParam("password", password). queryParam("phone", phoneNumber). getAsJsonMapAsync(new Callback<Response<Map>>() { @Override public void onSucess(Response<Map> value) { me = new User(); me.getPropertyIndex().populateFromMap( value.getResponseData()); Preferences.set("token", me.authToken.get()); PreferencesObject.create(me).bind(); onSuccess.onSucess(me); } @Override public void onError(Object sender, Throwable err, int errorCode, String errorMessage) { onError.onError(null, err, errorCode, errorMessage); } }); UserService (Client Side) The login method accepts a phone and password and is invoked after we validated the phone. It can succeed or fail.
  • 14. public static void loginWithPhone(String phoneNumber, String password, final SuccessCallback<User> onSuccess, final FailureCallback<Object> onError) { Rest.get(SERVER_URL + "user/login"). acceptJson(). queryParam("password", password). queryParam("phone", phoneNumber). getAsJsonMapAsync(new Callback<Response<Map>>() { @Override public void onSucess(Response<Map> value) { me = new User(); me.getPropertyIndex().populateFromMap( value.getResponseData()); Preferences.set("token", me.authToken.get()); PreferencesObject.create(me).bind(); onSuccess.onSucess(me); } @Override public void onError(Object sender, Throwable err, int errorCode, String errorMessage) { onError.onError(null, err, errorCode, errorMessage); } }); UserService (Client Side) If we get back a token that means the UserAuthenticationException wasn't thrown in the server and we can set it into the Preferences otherwise we need to send a failure callback