SlideShare a Scribd company logo
1 of 13
Download to read offline
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

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

- the modification will be done in Main class- first, asks the use.pdf
- the modification will be done in Main class- first, asks the use.pdf- the modification will be done in Main class- first, asks the use.pdf
- the modification will be done in Main class- first, asks the use.pdf
hanumanparsadhsr
 
Google Plus SignIn : l'Authentification Google
Google Plus SignIn : l'Authentification GoogleGoogle Plus SignIn : l'Authentification Google
Google Plus SignIn : l'Authentification Google
Mathias Seguy
 

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

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

More from ShaiAlmog1

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 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
 
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
 

Recently uploaded

TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc
 
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptxHarnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
FIDO Alliance
 
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
panagenda
 

Recently uploaded (20)

The Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and InsightThe Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and Insight
 
How to Check GPS Location with a Live Tracker in Pakistan
How to Check GPS Location with a Live Tracker in PakistanHow to Check GPS Location with a Live Tracker in Pakistan
How to Check GPS Location with a Live Tracker in Pakistan
 
Introduction to FIDO Authentication and Passkeys.pptx
Introduction to FIDO Authentication and Passkeys.pptxIntroduction to FIDO Authentication and Passkeys.pptx
Introduction to FIDO Authentication and Passkeys.pptx
 
Intro to Passkeys and the State of Passwordless.pptx
Intro to Passkeys and the State of Passwordless.pptxIntro to Passkeys and the State of Passwordless.pptx
Intro to Passkeys and the State of Passwordless.pptx
 
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
 
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptxHarnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
 
Event-Driven Architecture Masterclass: Challenges in Stream Processing
Event-Driven Architecture Masterclass: Challenges in Stream ProcessingEvent-Driven Architecture Masterclass: Challenges in Stream Processing
Event-Driven Architecture Masterclass: Challenges in Stream Processing
 
Easier, Faster, and More Powerful – Notes Document Properties Reimagined
Easier, Faster, and More Powerful – Notes Document Properties ReimaginedEasier, Faster, and More Powerful – Notes Document Properties Reimagined
Easier, Faster, and More Powerful – Notes Document Properties Reimagined
 
How we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdfHow we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdf
 
الأمن السيبراني - ما لا يسع للمستخدم جهله
الأمن السيبراني - ما لا يسع للمستخدم جهلهالأمن السيبراني - ما لا يسع للمستخدم جهله
الأمن السيبراني - ما لا يسع للمستخدم جهله
 
ERP Contender Series: Acumatica vs. Sage Intacct
ERP Contender Series: Acumatica vs. Sage IntacctERP Contender Series: Acumatica vs. Sage Intacct
ERP Contender Series: Acumatica vs. Sage Intacct
 
WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024
 
ChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps ProductivityChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps Productivity
 
How to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cfHow to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cf
 
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
 
Oauth 2.0 Introduction and Flows with MuleSoft
Oauth 2.0 Introduction and Flows with MuleSoftOauth 2.0 Introduction and Flows with MuleSoft
Oauth 2.0 Introduction and Flows with MuleSoft
 
Overview of Hyperledger Foundation
Overview of Hyperledger FoundationOverview of Hyperledger Foundation
Overview of Hyperledger Foundation
 
AI mind or machine power point presentation
AI mind or machine power point presentationAI mind or machine power point presentation
AI mind or machine power point presentation
 
JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptx
 
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
 

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.