SlideShare a Scribd company logo
Creating an Uber Clone - Part XXXIV
Next we’ll integrate the facebook login process into the code
App Id
© Codename One 2017 all rights reserved
To get the native login working we only need one step: Add the build hint facebook.appId=AppId.

AppId is the id from the dashboard on the facebook app page. This will make Facebook work on the devices almost seamlessly. 

Notice that since we have effectively 2 apps we’ll need to add an appId to the user app and the driver app
facebook.addActionListener(e -> {
final Login fb = FacebookConnect.getInstance();
if(UberClone.isDriverMode()) {
fb.setClientId("value for driver app");
fb.setClientSecret("value for driver app");
} else {
fb.setClientId("value for user app");
fb.setClientSecret("value for user app");
}
fb.setRedirectURI("https://www.codenameone.com/");
fb.setCallback(new LoginCallback() {
@Override
public void loginFailed(String errorMessage) {
ToastBar.showErrorMessage("Login failed: " + errorMessage);
}
@Override
public void loginSuccessful() {
String token = fb.getAccessToken().getToken();
new EnterPasswordForm(null, token, null).show();
}
});
fb.doLogin();
});
FacebookOrGoogleLoginForm
To get login working on the simulator we'll need a bit more. We'll also need to write code that supports the login process within the FacebookOrGoogleLoginForm class.

FacebookConnect is a subclass of the Login class that lets us login into facebook and request publish permissions if necessary
facebook.addActionListener(e -> {
final Login fb = FacebookConnect.getInstance();
if(UberClone.isDriverMode()) {
fb.setClientId("value for driver app");
fb.setClientSecret("value for driver app");
} else {
fb.setClientId("value for user app");
fb.setClientSecret("value for user app");
}
fb.setRedirectURI("https://www.codenameone.com/");
fb.setCallback(new LoginCallback() {
@Override
public void loginFailed(String errorMessage) {
ToastBar.showErrorMessage("Login failed: " + errorMessage);
}
@Override
public void loginSuccessful() {
String token = fb.getAccessToken().getToken();
new EnterPasswordForm(null, token, null).show();
}
});
fb.doLogin();
});
FacebookOrGoogleLoginForm
The client id and secret aren't used on devices. These are here strictly for the benefit of the simulator! 

If you don't need to debug on the simulator the lines until setCallback are redundant...

Notice that we have two versions of these values for the User app and the driver app.
facebook.addActionListener(e -> {
final Login fb = FacebookConnect.getInstance();
if(UberClone.isDriverMode()) {
fb.setClientId("value for driver app");
fb.setClientSecret("value for driver app");
} else {
fb.setClientId("value for user app");
fb.setClientSecret("value for user app");
}
fb.setRedirectURI("https://www.codenameone.com/");
fb.setCallback(new LoginCallback() {
@Override
public void loginFailed(String errorMessage) {
ToastBar.showErrorMessage("Login failed: " + errorMessage);
}
@Override
public void loginSuccessful() {
String token = fb.getAccessToken().getToken();
new EnterPasswordForm(null, token, null).show();
}
});
fb.doLogin();
});
FacebookOrGoogleLoginForm
The callback is invoked upon login success/failure, if a login is successful we get the token from facebook which is an "authorization token". This token allows us to
access information within the Facebook graph API to query facts about the user. Notice we have a new constructor for EnterPasswordForm which I will discuss soon
facebook.addActionListener(e -> {
final Login fb = FacebookConnect.getInstance();
if(UberClone.isDriverMode()) {
fb.setClientId("value for driver app");
fb.setClientSecret("value for driver app");
} else {
fb.setClientId("value for user app");
fb.setClientSecret("value for user app");
}
fb.setRedirectURI("https://www.codenameone.com/");
fb.setCallback(new LoginCallback() {
@Override
public void loginFailed(String errorMessage) {
ToastBar.showErrorMessage("Login failed: " + errorMessage);
}
@Override
public void loginSuccessful() {
String token = fb.getAccessToken().getToken();
new EnterPasswordForm(null, token, null).show();
}
});
fb.doLogin();
});
FacebookOrGoogleLoginForm
This triggers the actual login but the method is asynchronous and login will only actually succeed or fail when the callback is reached
public EnterPasswordForm(String phoneNumber, String facebookId, String googleId) {
super(new BorderLayout());
Form previous = getCurrentForm();
InfiniteProgress ip = new InfiniteProgress();
Dialog dlg = ip.showInifiniteBlocking();
boolean exists = UserService.userExists(phoneNumber, facebookId, googleId);
// same code as before snipped...
fab.addActionListener(e -> {
Dialog ipDlg = new InfiniteProgress().showInifiniteBlocking();
if(exists) {
UserService.login(phoneNumber, facebookId, googleId, password.getText(), (value) -> {
MapForm.get().show();
}, (sender, err, errorCode, errorMessage) -> {
ipDlg.dispose();
error.setText("Login error");
error.setVisible(true);
revalidate();
});
} else {
if(UserService.addNewUser(new User().
phone.set(phoneNumber).
facebookId.set(facebookId).
googleId.set(googleId).
password.set(password.getText()).
driver.set(UberClone.isDriverMode()))) {
MapForm.get().show();
} else {
EnterPasswordForm
Before we go to the Google login support lets look at the additional changes we need to get both Facebook and Google working. I already discussed the changes to
EnterPasswordForm so lets start there…

The constructor accepts one of the 3 options the other two should be null in this case
public EnterPasswordForm(String phoneNumber, String facebookId, String googleId) {
super(new BorderLayout());
Form previous = getCurrentForm();
InfiniteProgress ip = new InfiniteProgress();
Dialog dlg = ip.showInifiniteBlocking();
boolean exists = UserService.userExists(phoneNumber, facebookId, googleId);
// same code as before snipped...
fab.addActionListener(e -> {
Dialog ipDlg = new InfiniteProgress().showInifiniteBlocking();
if(exists) {
UserService.login(phoneNumber, facebookId, googleId, password.getText(), (value) -> {
MapForm.get().show();
}, (sender, err, errorCode, errorMessage) -> {
ipDlg.dispose();
error.setText("Login error");
error.setVisible(true);
revalidate();
});
} else {
if(UserService.addNewUser(new User().
phone.set(phoneNumber).
facebookId.set(facebookId).
googleId.set(googleId).
password.set(password.getText()).
driver.set(UberClone.isDriverMode()))) {
MapForm.get().show();
} else {
EnterPasswordForm
I also updated the UserService method accordingly, I'll get into that shortly. Notice I snipped some code below here to keep the entire block in one page but it’s still
there…
public EnterPasswordForm(String phoneNumber, String facebookId, String googleId) {
super(new BorderLayout());
Form previous = getCurrentForm();
InfiniteProgress ip = new InfiniteProgress();
Dialog dlg = ip.showInifiniteBlocking();
boolean exists = UserService.userExists(phoneNumber, facebookId, googleId);
// same code as before snipped...
fab.addActionListener(e -> {
Dialog ipDlg = new InfiniteProgress().showInifiniteBlocking();
if(exists) {
UserService.login(phoneNumber, facebookId, googleId, password.getText(), (value) -> {
MapForm.get().show();
}, (sender, err, errorCode, errorMessage) -> {
ipDlg.dispose();
error.setText("Login error");
error.setVisible(true);
revalidate();
});
} else {
if(UserService.addNewUser(new User().
phone.set(phoneNumber).
facebookId.set(facebookId).
googleId.set(googleId).
password.set(password.getText()).
driver.set(UberClone.isDriverMode()))) {
MapForm.get().show();
} else {
EnterPasswordForm
The login method now accepts the Google/Facebook credentials as an optional argument
public EnterPasswordForm(String phoneNumber, String facebookId, String googleId) {
super(new BorderLayout());
Form previous = getCurrentForm();
InfiniteProgress ip = new InfiniteProgress();
Dialog dlg = ip.showInifiniteBlocking();
boolean exists = UserService.userExists(phoneNumber, facebookId, googleId);
// same code as before snipped...
fab.addActionListener(e -> {
Dialog ipDlg = new InfiniteProgress().showInifiniteBlocking();
if(exists) {
UserService.login(phoneNumber, facebookId, googleId, password.getText(), (value) -> {
MapForm.get().show();
}, (sender, err, errorCode, errorMessage) -> {
ipDlg.dispose();
error.setText("Login error");
error.setVisible(true);
revalidate();
});
} else {
if(UserService.addNewUser(new User().
phone.set(phoneNumber).
facebookId.set(facebookId).
googleId.set(googleId).
password.set(password.getText()).
driver.set(UberClone.isDriverMode()))) {
MapForm.get().show();
} else {
EnterPasswordForm
Two of the three values for identification will be null so we can set all of them and only one will have a value
public static boolean userExists(String phoneNumber, String facebookId, String googleId) {
if(phoneNumber != null) {
return userExistsPhone(phoneNumber);
}
if(facebookId != null) {
return userExistsFacebook(facebookId);
}
return userExistsGoogle(googleId);
}
public static boolean userExistsPhone(String phoneNumber) {
return userExistsImpl("user/exists", phoneNumber);
}
public static boolean userExistsFacebook(String phoneNumber) {
return userExistsImpl("user/existsFacebook", phoneNumber);
}
public static boolean userExistsGoogle(String phoneNumber) {
return userExistsImpl("user/existsGoogle", phoneNumber);
}
private static boolean userExistsImpl(String url, String val) {
Response<byte[]> b = Rest.get(SERVER_URL + url).
acceptJson().
queryParam("v", val).getAsBytes();
if(b.getResponseCode() == 200) {
// the t from true
return b.getResponseData()[0] == (byte)'t';
}
return false;
UserService
Next lets see the changes to the UserService class. 

This is the main method we use which we broke up for the other types
public static boolean userExists(String phoneNumber, String facebookId, String googleId) {
if(phoneNumber != null) {
return userExistsPhone(phoneNumber);
}
if(facebookId != null) {
return userExistsFacebook(facebookId);
}
return userExistsGoogle(googleId);
}
public static boolean userExistsPhone(String phoneNumber) {
return userExistsImpl("user/exists", phoneNumber);
}
public static boolean userExistsFacebook(String phoneNumber) {
return userExistsImpl("user/existsFacebook", phoneNumber);
}
public static boolean userExistsGoogle(String phoneNumber) {
return userExistsImpl("user/existsGoogle", phoneNumber);
}
private static boolean userExistsImpl(String url, String val) {
Response<byte[]> b = Rest.get(SERVER_URL + url).
acceptJson().
queryParam("v", val).getAsBytes();
if(b.getResponseCode() == 200) {
// the t from true
return b.getResponseData()[0] == (byte)'t';
}
return false;
UserService
This generic implementation demonstrates why I chose to change the argument name from phone to v so it can now suite all the permutations of this method
return userExistsImpl("user/existsFacebook", phoneNumber);
}
public static boolean userExistsGoogle(String phoneNumber) {
return userExistsImpl("user/existsGoogle", phoneNumber);
}
private static boolean userExistsImpl(String url, String val) {
Response<byte[]> b = Rest.get(SERVER_URL + url).
acceptJson().
queryParam("v", val).getAsBytes();
if(b.getResponseCode() == 200) {
// the t from true
return b.getResponseData()[0] == (byte)'t';
}
return false;
}
public static void login(String phoneNumber, String facebookId, String googleId, String password,
final SuccessCallback<User> onSuccess, final FailureCallback<Object> onError) {
Rest.get(SERVER_URL + "user/login").
acceptJson().
queryParam("password", password).
queryParam("phone", phoneNumber).
queryParam("facebookId", facebookId).
queryParam("googleId", googleId).
getAsJsonMapAsync(new Callback<Response<Map>>() {
// this code was unchanged
});
}
UserService
Login is almost identical to the original code. I added the new values to the mix. If they are null the arguments won't be sent and everything will work as expected.

Once this is done Facebook login should work on the device and simulator.

More Related Content

PDF
Creating an Uber Clone - Part XXXIV.pdf
PDF
Creating an Uber Clone - Part XIV - Transcript.pdf
PPTX
Angular Workshop_Sarajevo2
PDF
Creating a Facebook Clone - Part XLVI - Transcript.pdf
PDF
JSLab. Алексей Волков. "React на практике"
PDF
Creating an Uber Clone - Part XXXIX.pdf
PDF
Building Large jQuery Applications
PDF
Creating a Facebook Clone - Part XXVIII - Transcript.pdf
Creating an Uber Clone - Part XXXIV.pdf
Creating an Uber Clone - Part XIV - Transcript.pdf
Angular Workshop_Sarajevo2
Creating a Facebook Clone - Part XLVI - Transcript.pdf
JSLab. Алексей Волков. "React на практике"
Creating an Uber Clone - Part XXXIX.pdf
Building Large jQuery Applications
Creating a Facebook Clone - Part XXVIII - Transcript.pdf

Similar to Creating an Uber Clone - Part XXXIV - Transcript.pdf (20)

PDF
Creating a Whatsapp Clone - Part XIV - Transcript.pdf
PDF
Foundational Facebook Marketing
PDF
Beginner’s tutorial (part 2) how to integrate redux-saga in react native app
PDF
WordPress Realtime - WordCamp São Paulo 2015
PPTX
Data Binding: Is It the Next Big Thing?
KEY
jQuery Bay Area Conference 2010
PDF
Android Testing
PDF
- the modification will be done in Main class- first, asks the use.pdf
PDF
Creating an Uber Clone - Part XXXX.pdf
PDF
Clean Javascript
PDF
Creating an Uber Clone - Part XXIX - Transcript.pdf
PDF
Curso Symfony - Clase 4
PDF
SQLite and ORM Binding - Part 2 - Transcript.pdf
PDF
Android Quiz App – Test Your IQ.pdf
PDF
Serverless Angular, Material, Firebase and Google Cloud applications
PDF
Mobile 2.0 Open Ideas WorkShop: Building Social Media Enabled Apps on Android
PDF
Creating a Facebook Clone - Part X - Transcript.pdf
PPTX
2008 - TechDays PT: WCF, JSON and AJAX for performance and manageability
PDF
Creating an Uber Clone - Part XXXX - Transcript.pdf
PPTX
Google Plus SignIn : l'Authentification Google
Creating a Whatsapp Clone - Part XIV - Transcript.pdf
Foundational Facebook Marketing
Beginner’s tutorial (part 2) how to integrate redux-saga in react native app
WordPress Realtime - WordCamp São Paulo 2015
Data Binding: Is It the Next Big Thing?
jQuery Bay Area Conference 2010
Android Testing
- the modification will be done in Main class- first, asks the use.pdf
Creating an Uber Clone - Part XXXX.pdf
Clean Javascript
Creating an Uber Clone - Part XXIX - Transcript.pdf
Curso Symfony - Clase 4
SQLite and ORM Binding - Part 2 - Transcript.pdf
Android Quiz App – Test Your IQ.pdf
Serverless Angular, Material, Firebase and Google Cloud applications
Mobile 2.0 Open Ideas WorkShop: Building Social Media Enabled Apps on Android
Creating a Facebook Clone - Part X - Transcript.pdf
2008 - TechDays PT: WCF, JSON and AJAX for performance and manageability
Creating an Uber Clone - Part XXXX - Transcript.pdf
Google Plus SignIn : l'Authentification Google

More from ShaiAlmog1 (20)

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

Recently uploaded (20)

PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PPTX
Understanding_Digital_Forensics_Presentation.pptx
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Electronic commerce courselecture one. Pdf
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PPTX
MYSQL Presentation for SQL database connectivity
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PPTX
Cloud computing and distributed systems.
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Machine learning based COVID-19 study performance prediction
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Approach and Philosophy of On baking technology
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
“AI and Expert System Decision Support & Business Intelligence Systems”
Understanding_Digital_Forensics_Presentation.pptx
The AUB Centre for AI in Media Proposal.docx
The Rise and Fall of 3GPP – Time for a Sabbatical?
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Electronic commerce courselecture one. Pdf
Dropbox Q2 2025 Financial Results & Investor Presentation
MYSQL Presentation for SQL database connectivity
Reach Out and Touch Someone: Haptics and Empathic Computing
Review of recent advances in non-invasive hemoglobin estimation
Chapter 3 Spatial Domain Image Processing.pdf
Cloud computing and distributed systems.
Unlocking AI with Model Context Protocol (MCP)
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Machine learning based COVID-19 study performance prediction
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Encapsulation_ Review paper, used for researhc scholars
Approach and Philosophy of On baking technology

Creating an Uber Clone - Part XXXIV - Transcript.pdf

  • 1. Creating an Uber Clone - Part XXXIV Next we’ll integrate the facebook login process into the code
  • 2. App Id © Codename One 2017 all rights reserved To get the native login working we only need one step: Add the build hint facebook.appId=AppId. AppId is the id from the dashboard on the facebook app page. This will make Facebook work on the devices almost seamlessly. Notice that since we have effectively 2 apps we’ll need to add an appId to the user app and the driver app
  • 3. facebook.addActionListener(e -> { final Login fb = FacebookConnect.getInstance(); if(UberClone.isDriverMode()) { fb.setClientId("value for driver app"); fb.setClientSecret("value for driver app"); } else { fb.setClientId("value for user app"); fb.setClientSecret("value for user app"); } fb.setRedirectURI("https://www.codenameone.com/"); fb.setCallback(new LoginCallback() { @Override public void loginFailed(String errorMessage) { ToastBar.showErrorMessage("Login failed: " + errorMessage); } @Override public void loginSuccessful() { String token = fb.getAccessToken().getToken(); new EnterPasswordForm(null, token, null).show(); } }); fb.doLogin(); }); FacebookOrGoogleLoginForm To get login working on the simulator we'll need a bit more. We'll also need to write code that supports the login process within the FacebookOrGoogleLoginForm class. FacebookConnect is a subclass of the Login class that lets us login into facebook and request publish permissions if necessary
  • 4. facebook.addActionListener(e -> { final Login fb = FacebookConnect.getInstance(); if(UberClone.isDriverMode()) { fb.setClientId("value for driver app"); fb.setClientSecret("value for driver app"); } else { fb.setClientId("value for user app"); fb.setClientSecret("value for user app"); } fb.setRedirectURI("https://www.codenameone.com/"); fb.setCallback(new LoginCallback() { @Override public void loginFailed(String errorMessage) { ToastBar.showErrorMessage("Login failed: " + errorMessage); } @Override public void loginSuccessful() { String token = fb.getAccessToken().getToken(); new EnterPasswordForm(null, token, null).show(); } }); fb.doLogin(); }); FacebookOrGoogleLoginForm The client id and secret aren't used on devices. These are here strictly for the benefit of the simulator! 
 If you don't need to debug on the simulator the lines until setCallback are redundant...
 Notice that we have two versions of these values for the User app and the driver app.
  • 5. facebook.addActionListener(e -> { final Login fb = FacebookConnect.getInstance(); if(UberClone.isDriverMode()) { fb.setClientId("value for driver app"); fb.setClientSecret("value for driver app"); } else { fb.setClientId("value for user app"); fb.setClientSecret("value for user app"); } fb.setRedirectURI("https://www.codenameone.com/"); fb.setCallback(new LoginCallback() { @Override public void loginFailed(String errorMessage) { ToastBar.showErrorMessage("Login failed: " + errorMessage); } @Override public void loginSuccessful() { String token = fb.getAccessToken().getToken(); new EnterPasswordForm(null, token, null).show(); } }); fb.doLogin(); }); FacebookOrGoogleLoginForm The callback is invoked upon login success/failure, if a login is successful we get the token from facebook which is an "authorization token". This token allows us to access information within the Facebook graph API to query facts about the user. Notice we have a new constructor for EnterPasswordForm which I will discuss soon
  • 6. facebook.addActionListener(e -> { final Login fb = FacebookConnect.getInstance(); if(UberClone.isDriverMode()) { fb.setClientId("value for driver app"); fb.setClientSecret("value for driver app"); } else { fb.setClientId("value for user app"); fb.setClientSecret("value for user app"); } fb.setRedirectURI("https://www.codenameone.com/"); fb.setCallback(new LoginCallback() { @Override public void loginFailed(String errorMessage) { ToastBar.showErrorMessage("Login failed: " + errorMessage); } @Override public void loginSuccessful() { String token = fb.getAccessToken().getToken(); new EnterPasswordForm(null, token, null).show(); } }); fb.doLogin(); }); FacebookOrGoogleLoginForm This triggers the actual login but the method is asynchronous and login will only actually succeed or fail when the callback is reached
  • 7. public EnterPasswordForm(String phoneNumber, String facebookId, String googleId) { super(new BorderLayout()); Form previous = getCurrentForm(); InfiniteProgress ip = new InfiniteProgress(); Dialog dlg = ip.showInifiniteBlocking(); boolean exists = UserService.userExists(phoneNumber, facebookId, googleId); // same code as before snipped... fab.addActionListener(e -> { Dialog ipDlg = new InfiniteProgress().showInifiniteBlocking(); if(exists) { UserService.login(phoneNumber, facebookId, googleId, password.getText(), (value) -> { MapForm.get().show(); }, (sender, err, errorCode, errorMessage) -> { ipDlg.dispose(); error.setText("Login error"); error.setVisible(true); revalidate(); }); } else { if(UserService.addNewUser(new User(). phone.set(phoneNumber). facebookId.set(facebookId). googleId.set(googleId). password.set(password.getText()). driver.set(UberClone.isDriverMode()))) { MapForm.get().show(); } else { EnterPasswordForm Before we go to the Google login support lets look at the additional changes we need to get both Facebook and Google working. I already discussed the changes to EnterPasswordForm so lets start there… The constructor accepts one of the 3 options the other two should be null in this case
  • 8. public EnterPasswordForm(String phoneNumber, String facebookId, String googleId) { super(new BorderLayout()); Form previous = getCurrentForm(); InfiniteProgress ip = new InfiniteProgress(); Dialog dlg = ip.showInifiniteBlocking(); boolean exists = UserService.userExists(phoneNumber, facebookId, googleId); // same code as before snipped... fab.addActionListener(e -> { Dialog ipDlg = new InfiniteProgress().showInifiniteBlocking(); if(exists) { UserService.login(phoneNumber, facebookId, googleId, password.getText(), (value) -> { MapForm.get().show(); }, (sender, err, errorCode, errorMessage) -> { ipDlg.dispose(); error.setText("Login error"); error.setVisible(true); revalidate(); }); } else { if(UserService.addNewUser(new User(). phone.set(phoneNumber). facebookId.set(facebookId). googleId.set(googleId). password.set(password.getText()). driver.set(UberClone.isDriverMode()))) { MapForm.get().show(); } else { EnterPasswordForm I also updated the UserService method accordingly, I'll get into that shortly. Notice I snipped some code below here to keep the entire block in one page but it’s still there…
  • 9. public EnterPasswordForm(String phoneNumber, String facebookId, String googleId) { super(new BorderLayout()); Form previous = getCurrentForm(); InfiniteProgress ip = new InfiniteProgress(); Dialog dlg = ip.showInifiniteBlocking(); boolean exists = UserService.userExists(phoneNumber, facebookId, googleId); // same code as before snipped... fab.addActionListener(e -> { Dialog ipDlg = new InfiniteProgress().showInifiniteBlocking(); if(exists) { UserService.login(phoneNumber, facebookId, googleId, password.getText(), (value) -> { MapForm.get().show(); }, (sender, err, errorCode, errorMessage) -> { ipDlg.dispose(); error.setText("Login error"); error.setVisible(true); revalidate(); }); } else { if(UserService.addNewUser(new User(). phone.set(phoneNumber). facebookId.set(facebookId). googleId.set(googleId). password.set(password.getText()). driver.set(UberClone.isDriverMode()))) { MapForm.get().show(); } else { EnterPasswordForm The login method now accepts the Google/Facebook credentials as an optional argument
  • 10. public EnterPasswordForm(String phoneNumber, String facebookId, String googleId) { super(new BorderLayout()); Form previous = getCurrentForm(); InfiniteProgress ip = new InfiniteProgress(); Dialog dlg = ip.showInifiniteBlocking(); boolean exists = UserService.userExists(phoneNumber, facebookId, googleId); // same code as before snipped... fab.addActionListener(e -> { Dialog ipDlg = new InfiniteProgress().showInifiniteBlocking(); if(exists) { UserService.login(phoneNumber, facebookId, googleId, password.getText(), (value) -> { MapForm.get().show(); }, (sender, err, errorCode, errorMessage) -> { ipDlg.dispose(); error.setText("Login error"); error.setVisible(true); revalidate(); }); } else { if(UserService.addNewUser(new User(). phone.set(phoneNumber). facebookId.set(facebookId). googleId.set(googleId). password.set(password.getText()). driver.set(UberClone.isDriverMode()))) { MapForm.get().show(); } else { EnterPasswordForm Two of the three values for identification will be null so we can set all of them and only one will have a value
  • 11. public static boolean userExists(String phoneNumber, String facebookId, String googleId) { if(phoneNumber != null) { return userExistsPhone(phoneNumber); } if(facebookId != null) { return userExistsFacebook(facebookId); } return userExistsGoogle(googleId); } public static boolean userExistsPhone(String phoneNumber) { return userExistsImpl("user/exists", phoneNumber); } public static boolean userExistsFacebook(String phoneNumber) { return userExistsImpl("user/existsFacebook", phoneNumber); } public static boolean userExistsGoogle(String phoneNumber) { return userExistsImpl("user/existsGoogle", phoneNumber); } private static boolean userExistsImpl(String url, String val) { Response<byte[]> b = Rest.get(SERVER_URL + url). acceptJson(). queryParam("v", val).getAsBytes(); if(b.getResponseCode() == 200) { // the t from true return b.getResponseData()[0] == (byte)'t'; } return false; UserService Next lets see the changes to the UserService class. This is the main method we use which we broke up for the other types
  • 12. public static boolean userExists(String phoneNumber, String facebookId, String googleId) { if(phoneNumber != null) { return userExistsPhone(phoneNumber); } if(facebookId != null) { return userExistsFacebook(facebookId); } return userExistsGoogle(googleId); } public static boolean userExistsPhone(String phoneNumber) { return userExistsImpl("user/exists", phoneNumber); } public static boolean userExistsFacebook(String phoneNumber) { return userExistsImpl("user/existsFacebook", phoneNumber); } public static boolean userExistsGoogle(String phoneNumber) { return userExistsImpl("user/existsGoogle", phoneNumber); } private static boolean userExistsImpl(String url, String val) { Response<byte[]> b = Rest.get(SERVER_URL + url). acceptJson(). queryParam("v", val).getAsBytes(); if(b.getResponseCode() == 200) { // the t from true return b.getResponseData()[0] == (byte)'t'; } return false; UserService This generic implementation demonstrates why I chose to change the argument name from phone to v so it can now suite all the permutations of this method
  • 13. return userExistsImpl("user/existsFacebook", phoneNumber); } public static boolean userExistsGoogle(String phoneNumber) { return userExistsImpl("user/existsGoogle", phoneNumber); } private static boolean userExistsImpl(String url, String val) { Response<byte[]> b = Rest.get(SERVER_URL + url). acceptJson(). queryParam("v", val).getAsBytes(); if(b.getResponseCode() == 200) { // the t from true return b.getResponseData()[0] == (byte)'t'; } return false; } public static void login(String phoneNumber, String facebookId, String googleId, String password, final SuccessCallback<User> onSuccess, final FailureCallback<Object> onError) { Rest.get(SERVER_URL + "user/login"). acceptJson(). queryParam("password", password). queryParam("phone", phoneNumber). queryParam("facebookId", facebookId). queryParam("googleId", googleId). getAsJsonMapAsync(new Callback<Response<Map>>() { // this code was unchanged }); } UserService Login is almost identical to the original code. I added the new values to the mix. If they are null the arguments won't be sent and everything will work as expected. Once this is done Facebook login should work on the device and simulator.