Codename one FacebookConnect - codenameone

I'm currently trying out Codename One for a cross-platform mobile app development and the app requires a social login. I am trying to introduce facebook login but it doesn't work. What may I be doing wrong?
Below is my code which throughs an error:
public class MyApplication {
private Form current;
private Resources theme;
private String tokenPrefix;
private String fullName;
private String uniqueId;
private String imageURL;
private static EncodedImage userPlaceholder;
private EncodedImage roundPlaceholder;
public void start() {
if (current != null) {
current.show();
return;
}
Form facebook = new Form(new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER));
facebook.getTitleArea().setUIID("Container");
Button connect = new Button("Login with facebook");
Container c = BoxLayout.encloseY(connect);
facebook.add(BorderLayout.CENTER, c);
connect.addActionListener((evt) -> {
/* tokenPrefix = "facebook";
Login fb = FacebookConnect.getInstance();
fb.setClientId("XXXXXXXXXXXXXXXXX");
fb.setRedirectURI("http://localhost/callback");
fb.setClientSecret("xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
doLogin(fb, new FacebookData(), false); */
String clientId = "XXXXXXXXXXXXXXXXX";
String redirectURI = "http://www.codenameone.com/";
String clientSecret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
Login fb = FacebookConnect.getInstance();
fb.setClientId(clientId);
fb.setRedirectURI(redirectURI);
fb.setClientSecret(clientSecret);
Log.p("login event triggered");
doLogin(fb, new FacebookData(), false);
/* if(!fb.isUserLoggedIn()){
doLogin(fb, new FacebookData(),false);
}else{
//get the token and now you can query the facebook API
String token = fb.getAccessToken().getToken();
} */
});
facebook.show();
}
void doLogin(Login lg, UserData data, boolean forceLogin) {
if (!forceLogin) {
if (lg.isUserLoggedIn()) {
Log.p("Fetching data......");
showContactsForm();
return;
}
String t = Preferences.get(tokenPrefix + "token", (String) null);
if (t != null) {
long tokenExpires = Preferences.get(tokenPrefix + "tokenExpires", (long) -1);
if (tokenExpires < 0 || tokenExpires > System.currentTimeMillis()) {
//we are still logged in
Log.p("Fetching data......");
showContactsForm();
return;
}
}
}
lg.setCallback(new LoginCallback() {
public void loginFailed(String errorMessage) {
Log.p("Error occured");
Dialog.show("Error Logging in", "There was an error logging in:" + errorMessage, "OK", null);
}
public void loginSuccessful() {
Log.p("doLogin started");
// when login is successful we fetch the full data
data.fetchData(lg.getAccessToken().getToken(), () -> {
// we store the values of result into local variables
String uniqueId = data.getId();
String fullName = data.getName();
String imageURL = data.getImage();
// we then store the data into local cached storage so they will be around when we run the app next time
Preferences.set("fullName", fullName);
Preferences.set("uniqueId", uniqueId);
Preferences.set("imageURL", imageURL);
Preferences.set(tokenPrefix + "token", lg.getAccessToken().getToken());
// token expiration is in seconds from the current time, we convert it to a System.currentTimeMillis value so we can
// reference it in the future to check expiration
Preferences.set(tokenPrefix + "tokenExpires", tokenExpirationInMillis(lg.getAccessToken()));
showContactsForm();
Log.p("information fetched" + fullName + "_" + uniqueId + "_");
});
}
});
lg.doLogin();
}
long tokenExpirationInMillis(AccessToken token) {
String expires = token.getExpires();
if (expires != null && expires.length() > 0) {
try {
// when it will expire in seconds
long l = (long) (Float.parseFloat(expires) * 1000);
return System.currentTimeMillis() + l;
} catch (NumberFormatException err) {
// ignore invalid input
}
}
return -1;
}
static interface UserData {
public String getName();
public String getId();
public String getImage();
public void fetchData(String token, Runnable callback);
// public ContactData[] getContacts();
}
class FacebookData implements UserData {
String name;
String id;
String token;
#Override
public String getName() {
return name;
}
#Override
public String getId() {
return id;
}
#Override
public String getImage() {
return "http://graph.facebook.com/v2.8/" + id + "/picture";
}
#Override
public void fetchData(String token, Runnable callback) {
this.token = token;
ConnectionRequest req = new ConnectionRequest() {
#Override
protected void readResponse(InputStream input) throws IOException {
JSONParser parser = new JSONParser();
Map<String, Object> parsed = parser.parseJSON(new InputStreamReader(input, "UTF-8"));
name = (String) parsed.get("name");
id = (String) parsed.get("id");
}
#Override
protected void postResponse() {
callback.run();
}
#Override
protected void handleErrorResponseCode(int code, String message) {
//access token not valid anymore
if (code >= 400 && code <= 410) {
Log.p("error occured");
doLogin(FacebookConnect.getInstance(), FacebookData.this, true);
return;
}
super.handleErrorResponseCode(code, message);
}
};
req.setPost(false);
req.setUrl("https://graph.facebook.com/v2.8/me");
req.addArgumentNoEncoding("access_token", token);
NetworkManager.getInstance().addToQueue(req);
}
}
void showContactsForm() {
Form result = new Form(new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER_ABSOLUTE));
Label fname = new Label("Hello");
Label id = new Label("Facebook");
Container c = BoxLayout.encloseY(fname, id);
fname.setText(Preferences.get("fullName", fullName));
id.setText(Preferences.get("uniqueId", uniqueId));
result.add(BorderLayout.CENTER, c);
result.show();
}
}

Firstly, make sure your Facebook login is setup properly on Facebook Developers Console.
Here is how you get all information you need:
Take note of this line req.addArgumentNoEncoding("fields", "id,email,name,first_name,last_name,gender,age_range,picture.width(512).height(512),locale,link,timezone,updated_time");, That's where we tell Facebook what informations we need
I used Dialog to check output in processFacebookLogin() for debugging purpose instead of showContact()
void doLogin(Login lg, UserData data, boolean forceLogin) {
if (!forceLogin) {
if (lg.isUserLoggedIn()) {
processFacebookLogin(data);
return;
}
// if the user already logged in previously and we have a token
String token = Preferences.get(tokenPrefix + "token", (String) null);
if (getToolbar() != null) {
// we check the expiration of the token which we previously stored as System time
long tokenExpires = Preferences.get(tokenPrefix + "tokenExpires", (long) -1);
if (tokenExpires < 0 || tokenExpires > System.currentTimeMillis()) {
data.fetchData(token, () -> {
processFacebookLogin(data);
});
return;
}
}
}
lg.setCallback(new LoginCallback() {
#Override
public void loginFailed(String errorMessage) {
Dialog.show("Error Logging In", "There was an error logging in with Facebook: " + errorMessage, "Ok", null);
}
#Override
public void loginSuccessful() {
data.fetchData(lg.getAccessToken().getToken(), () -> {
Preferences.set(tokenPrefix + "token", lg.getAccessToken().getToken());
Preferences.set(tokenPrefix + "tokenExpires", tokenExpirationInMillis(lg.getAccessToken()));
processFacebookLogin(data);
});
}
});
lg.doLogin();
}
long tokenExpirationInMillis(AccessToken token) {
String expires = token.getExpires();
if (expires != null && expires.length() > 0) {
try {
// when it will expire in seconds
long l = (long) (Float.parseFloat(expires) * 1000);
return System.currentTimeMillis() + l;
} catch (NumberFormatException err) {
// ignore invalid input
}
}
return -1;
}
class FacebookData implements UserData {
String id;
String email;
String name;
String first_name;
String last_name;
String image;
String link;
String gender;
String locale;
Double timezone;
String updated_time;
String verified;
#Override
public String getId() {
return id;
}
#Override
public String getEmail() {
return email;
}
#Override
public String getFullName() {
return name;
}
#Override
public String getFirstName() {
return first_name;
}
#Override
public String getLastName() {
return last_name;
}
#Override
public String getGender() {
return gender;
}
#Override
public String getLink() {
return link;
}
#Override
public String getLocale() {
return locale;
}
#Override
public Double getTimezone() {
return timezone;
}
#Override
public String getUpdatedTime() {
return updated_time;
}
#Override
public String getImage() {
return image;
}
#Override
public void fetchData(String token, Runnable callback) {
ConnectionRequest req = new ConnectionRequest() {
#Override
protected void readResponse(InputStream input) throws IOException {
JSONParser parser = new JSONParser();
Map<String, Object> parsed = parser.parseJSON(new InputStreamReader(input, "UTF-8"));
id = (String) parsed.get("id");
email = (String) parsed.get("email");
name = (String) parsed.get("name");
first_name = (String) parsed.get("first_name");
last_name = (String) parsed.get("last_name");
link = (String) parsed.get("link");
gender = (String) parsed.get("gender");
locale = (String) parsed.get("locale");
timezone = (Double) parsed.get("timezone");
updated_time = (String) parsed.get("updated_time;");
verified = (String) parsed.get("verified");
image = (String) ((Map) ((Map) parsed.get("picture")).get("data")).get("url").toString();
}
#Override
protected void postResponse() {
callback.run();
}
#Override
protected void handleErrorResponseCode(int code, String message) {
//access token not valid anymore
if (code >= 400 && code <= 410) {
doLogin(FacebookConnect.getInstance(), FacebookData.this, true);
return;
}
super.handleErrorResponseCode(code, message);
}
};
req.setPost(false);
req.setUrl("https://graph.facebook.com/v2.8/me");
req.addArgumentNoEncoding("access_token", token);
req.addArgumentNoEncoding("fields", "id,email,name,first_name,last_name,gender,age_range,picture.width(512).height(512),locale,link,timezone,updated_time");
NetworkManager.getInstance().addToQueue(req);
}
}

Related

how to display database(name, photo, status and address) from firebase in listview?

this app doesn't use profile image as profile photo. but i want to add it with firebase.
I want to add/change from icon to user photo profile, data from firebase
I've tried it with the code below, everything in the user list turns into my photo, so it's weird.
please help me what should i do.how to display database(name, photo, status and address) from firebase in listview?
enter image description here
the result is like in this picture, the user photos are all the same
MyActivity Code:
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
getLocation();
View view2 = view;
Object item = getItem(i);
boolean z = item instanceof Channel;
String str = "";
if (z) {
Channel channel = (Channel) item;
if (view2 == null || view2.findViewById(R.id.channelname1) == null) {
view2 = this.inflater.inflate(R.layout.item_channel2, viewGroup, false);
}
TextView textView = (TextView) view2.findViewById(R.id.channelname1);
TextView textView2 = (TextView) view2.findViewById(R.id.chantopic);
ImageView imageView = (ImageView) view2.findViewById(R.id.channelicon);
Button join = (Button) view2.findViewById(R.id.join_btn2);
int icon_resource = R.drawable.inbox;
if(channel.bPassword) {
icon_resource = R.drawable.ic_lock;
imageView.setContentDescription(getString(R.string.text_passwdprot));
imageView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
}
else {
imageView.setContentDescription(null);
imageView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
}
imageView.setImageResource(icon_resource);
textView.setText(channel.szName);
textView2.setText(channel.szTopic);
int size = Utils.getUsers(channel.nChannelID, MainActivity.this.ttservice.getUsers()).size();
if (size > 0) {
str = String.format("%d ", Integer.valueOf(size));
}
TextView textView3 = (TextView) view2.findViewById(R.id.population);
textView3.setText(str);
if (size > 0) {
str = String.format("%d ", Integer.valueOf(size));
}
if(channel.nParentID == 0) {
// show server name as channel name for root channel
ServerProperties srvprop = new ServerProperties();
ttclient.getServerProperties(srvprop);
textView.setText(srvprop.szServerName);
viewptt.setVisibility(View.GONE);
}
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.join_btn2 : {
joinChannel(channel);
}
break;
}
}
};
join.setOnClickListener(listener);
join.setAccessibilityDelegate(accessibilityAssistant);
join.setEnabled(channel.nChannelID != ttclient.getMyChannelID());
}
else if (item instanceof dk.bearware.User) {
dk.bearware.User user = (dk.bearware.User) item;
if (view2 == null || view2.findViewById(R.id.txtUsername) == null) {
view2 = this.inflater.inflate(R.layout.list_users_grid, viewGroup, false);
}
imgBGWhite = view2.findViewById(R.id.imgBGWhite);
imgOff = view2.findViewById(R.id.imgOff);
imgOn = view2.findViewById(R.id.imgOn);
mImageView = (CircleImageView) view2.findViewById(R.id.imageView);
TextView txtLastDate= (TextView) view2.findViewById(R.id.txtLastDate);
TextView txtLastMsg= (TextView) view2.findViewById(R.id.txtLastMsg);
TextView txtUnreadCounter= (TextView) view2.findViewById(R.id.txtUnreadCounter);
mTxtUsername = (TextView) view2.findViewById(R.id.txtUsername);
status = (TextView) view2.findViewById(R.id.status);
txtLocationCity = (TextView) view2.findViewById(R.id.alamatKota);
txtLastDate.setVisibility(View.GONE);
txtUnreadCounter.setVisibility(View.GONE);
status.setText(status1);
txtLocationCity.setText(location);
firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
assert firebaseUser != null;
currentId = firebaseUser.getUid();
reference = FirebaseDatabase.getInstance().getReference(REF_USERS).child(currentId);
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
try {
if (dataSnapshot.hasChildren()) {
final User user = dataSnapshot.getValue(User.class);
assert user != null;
status.setText(user.getAbout());
txtLocationCity.setText(user.getUserAlamatKota());
Utils.setProfileImage(getApplicationContext(), user.getImageURL(), mImageView1);
}
} catch (Exception ignored) {
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
mTxtUsername.setText(Utils.getDisplayName(MainActivity.this.getBaseContext(), user));
try {
int size2 = Utils.getUsers(MainActivity.this.curchannel.nChannelID, MainActivity.this.ttservice.getUsers()).size();
TextView textView11 = MainActivity.this.recUserOnline;
textView11.setText(size2 + str);
textView11.setTextColor(YELLOW);
MainActivity.this.channelSekarang = MainActivity.this.curchannel.nChannelID;
MainActivity.this.textInfoChannel.setText(MainActivity.this.curchannel.szTopic);
TextView textView10 = textChannelSekarang;
textView10.setText(curchannel.szName + str);
} catch (Exception unused3) {
}
boolean talking = (user.uUserState & UserState.USERSTATE_VOICE) != 0;
boolean female = (user.nStatusMode & TeamTalkConstants.STATUSMODE_FEMALE) != 0;
boolean away = (user.nStatusMode & TeamTalkConstants.STATUSMODE_AWAY) != 0;
if(user.nUserID == ttservice.getTTInstance().getMyUserID()) {
talking = ttservice.isVoiceTransmitting();
}
if(talking) {
String name1 = Utils.getDisplayName(getBaseContext(), user);
mTxtUsername.setContentDescription(getString(R.string.user_state_now_speaking, name1));
if(female) {
imgBGWhite.setVisibility(View.VISIBLE);
imgOn.setVisibility(View.VISIBLE);
imgOff.setVisibility(View.GONE);
}
else {
imgBGWhite.setVisibility(View.VISIBLE);
imgOn.setVisibility(View.VISIBLE);
imgOff.setVisibility(View.GONE);
}
}
else{
imgBGWhite.setVisibility(View.GONE);
imgOn.setVisibility(View.GONE);
imgOff.setVisibility(View.GONE);
}
}
view2.setAccessibilityDelegate(MainActivity.this.accessibilityAssistant);
return view2;
}
User code:
public class User implements Serializable {
private String id;
private String username;
private String email;
private String imageURL;
private String status;
private String search;
private String password;
private boolean active;
private boolean typing;
private String typingwith;
private String about;
private String gender;
private String lastSeen;
private String userAlamat;
private boolean isChecked;
private boolean isAdmin;
private boolean isHost;
private boolean isCoHost;
private int userJenis = 0;
private String userNEGARA;
private String userPROVINSI;
private String userKOTA;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getImageURL() {
return imageURL;
}
public void setImageURL(String imageURL) {
this.imageURL = imageURL;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getSearch() {
return search;
}
public void setSearch(String search) {
this.search = search;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
public boolean isTyping() {
return typing;
}
public void setTyping(boolean typing) {
this.typing = typing;
}
public String getTypingwith() {
return typingwith;
}
public void setTypingwith(String typingwith) {
this.typingwith = typingwith;
}
public String getAbout() {
return about;
}
public void setAbout(String about) {
this.about = about;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getLastSeen() {
return lastSeen;
}
public void setLastSeen(String lastSeen) {
this.lastSeen = lastSeen;
}
public boolean isChecked() {
return isChecked;
}
public void setChecked(boolean checked) {
isChecked = checked;
}
public boolean isAdmin() {
return isAdmin;
}
public void setAdmin(boolean admin) {
isAdmin = admin;
}
public boolean isHost() {
return isHost;
}
public void setHost(boolean host) {
isHost = host;
}
public boolean isCoHost() {
return isCoHost;
}
public void setCoHost(boolean cohost) {
isCoHost = cohost;
}
public String setUserJenis(int i) {
this.userJenis = i;
return null;
}
public int getUserJenis() {
return this.userJenis;
}
public String getUserAlamatKota() {
return userKOTA;
}
public void setUserAlamatKota(String userKOTA) {
this.userKOTA = userKOTA;
}
#NotNull
#Override
public String toString() {
return "User{" +
"id='" + id + '\'' +
", username='" + username + '\'' +
", email='" + email + '\'' +
", status='" + status + '\'' +
", userKOTA='" + userKOTA + '\'' +
", userPROVINSI='" + userPROVINSI + '\'' +
", userNEGARA='" + userNEGARA + '\'' +
", imageURL='" + imageURL + '\'' +
", status='" + status + '\'' +
", search='" + search + '\'' +
", password='" + password + '\'' +
", active=" + active +
", typing=" + typing +
", typingwith='" + typingwith + '\'' +
", about='" + about + '\'' +
", gender='" + gender + '\'' +
", lastSeen='" + lastSeen + '\'' +
", isChecked=" + isChecked +
'}';
}
}

JSONArray cannot be converted to JSONObject error when used as similar code

I get this error when I did the same this to my register method, I used this on my Login and it works well, but in register I get the error that the array cannot be converted to JSONObject, I am trying to put the array to convert it to JSONObject to send it to my PHP code for the database
This is my register method
private void registerUser() {
final String phone = phonenumber.getText().toString().trim();
final String lname = lastname.getText().toString().trim();
final String fname = fullname.getText().toString().trim();
final String mname = middlename.getText().toString().trim();
final String add = address.getText().toString().trim();
final String count = country.getText().toString().trim();
//first we will do the validations
if (TextUtils.isEmpty(lname)) {
lastname.setError("Please your Last Name");
lastname.requestFocus();
return;
}
if (TextUtils.isEmpty(fname)) {
fullname.setError("Please enter your First Name");
fullname.requestFocus();
return;
}
if (TextUtils.isEmpty(add)) {
address.setError("Please enter your Address");
fullname.requestFocus();
return;
}
StringRequest stringRequest = new StringRequest(Request.Method.POST, URLs.URL_REGISTER,
new Response.Listener<String>() {
#Override
public void onResponse(String Response) {
try {
//converting response to json object
JSONObject obj = new JSONObject(Response);
//if no error in response
if (!obj.getBoolean("error")) {
Toast.makeText(getApplicationContext(), obj.getString("message"), Toast.LENGTH_SHORT).show();
//getting the user from the response
JSONObject userJson = obj.getJSONObject("user");
//creating a new user object
User user = new User(
userJson.getString("phone_number"),
userJson.getString("lastname"),
userJson.getString("fullname"),
userJson.getString("middleinitial"),
userJson.getString("country"),
userJson.getString("address")
);
//storing the user in shared preferences
SharedPrefManager.getInstance(getApplicationContext()).userLogin(user);
//starting the profile activity
finish();
startActivity(new Intent(getApplicationContext(), MainActivity.class));
} else {
Toast.makeText(getApplicationContext(), obj.getString("message"), Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_SHORT).show();
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("phone_number", phone);
params.put("lastname", lname);
params.put("fullname", fname);
params.put("middleinitial", mname);
params.put("country", count);
params.put("address",add);
return params;
}
};
VolleySingleton.getInstance(this).addToRequestQueue(stringRequest);
}
this code got the error of JSON Array cannot be converted while my Login Code with the same format is working
this is my login code:
private void userLogin(){
//first getting the values
final String phonenumber = etNumber.getText().toString();
//validating inputs
if (TextUtils.isEmpty(phonenumber)) {
etNumber.setError("Please enter your Number");
etNumber.requestFocus();
return;
}
//if everything is fine
StringRequest stringRequest = new StringRequest(Request.Method.POST, URLs.URL_LOGIN,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
//converting response to json object
JSONObject obj = new JSONObject(response);
//if no error in response
if (!obj.getBoolean("error")) {
Toast.makeText(getApplicationContext(), obj.getString("message"), Toast.LENGTH_SHORT).show();
//getting the user from the response
JSONObject userJson = obj.getJSONObject("user");
//creating a new user object
User user = new User(
userJson.getString("phone_number"),
userJson.getString("lastname"),
userJson.getString("fullname"),
userJson.getString("middleinitial"),
userJson.getString("country"),
userJson.getString("address")
);
//storing the user in shared preferences
SharedPrefManager.getInstance(getApplicationContext()).userLogin(user);
//starting the profile activity
finish();
startActivity(new Intent(getApplicationContext(), MainActivity.class));
} else {
Toast.makeText(getApplicationContext(), obj.getString("message"), Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_SHORT).show();
}
})
{
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("phone_number", phonenumber);
return params;
}
};
VolleySingleton.getInstance(this).addToRequestQueue(stringRequest);
}
and the error I got on my Logs is this:
W/System.err: org.json.JSONException: Value [] of type org.json.JSONArray cannot be converted to JSONObject
at org.json.JSON.typeMismatch(JSON.java:112)
at org.json.JSONObject.<init>(JSONObject.java:168)
at org.json.JSONObject.<init>(JSONObject.java:181)
at com.example.redwallet.Register$4.onResponse(Register.java:127)
W/System.err: at com.example.redwallet.Register$4.onResponse(Register.java:120)
at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:82)
at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:29)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:102)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:224)
at android.app.ActivityThread.main(ActivityThread.java:7562)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)

Error when creating a pagination with apex

No errors on the apex class screen. An unexpected error occurs when you press the search button.
I got an error when I added the pagination code in the second half.
There was no problem before that.
Why?
public with sharing class AccountListCon {
static List<String> TARGET_FIELDS = new List<String>{
'Name'
};
public SearchCondition condition{ get;set; }
public List<AccountList__c> results { get;set; }
public String sortingField { get;set; }
public void init(){
this.condition = new SearchCondition();
this.results = new List<AccountList__c>();
}
public PageReference clear(){
init();
return null;
}
public PageReference search() {
if( condition.validate() ){
return null;
}
String soqlQuery = condition.getSoqlQuery();
System.debug('[soql] ' + soqlQuery);
try{
this.results = database.query(soqlQuery);
System.debug(this.results);
}catch(DmlException e){
ApexPages.addMessages(e);
System.debug('[DmlException]' + e);
}catch(Exception e){
ApexPages.addMessages(e);
System.debug('[Exception]' + e);
}
return null;
}
public PageReference sort(){
if(this.sortingField == null ){
return null;
}
if(this.sortingField == this.condition.sortkey){
this.condition.setOrderReverse();
}
else {
this.condition.sortkey = this.sortingField;
}
search();
return null;
}
public Class SearchCondition {
private Time JST_AM0 = Time.newInstance(9, 0, 0, 0);
public AccountList__c obj {get;set;}
public SearchCondition() {
this.obj = new AccountList__c();
sortkey = 'LastModifiedDate';
order = 'DESC';
}
public String getSoqlQuery(){
List<String> param = new String[]{ getFieldList(), getWhere(), getOrder() };
return String.format('SELECT {0} FROM AccountList__c {1} {2} LIMIT 500', param);
}
private String getFieldList(){
return String.join(TARGET_FIELDS, ',');
}
private String getWhere(){
List<String> param = new String[]{ };
--Omission--
if(param.isEmpty()){
return '';
}
return 'WHERE ' + String.join(param, ' AND ');
}
private String getOrder(){
List<String> param = new String[]{ sortkey, order };
return String.format('ORDER BY {0} {1}', param);
}
private DateTime adjustJSTtoGMS(DateTime day){
JST_AM0 = Time.newInstance(15, 0, 0, 0);
return Datetime.newInstance(day.date(), JST_AM0);
}
--Omission--
private static final Integer PAGE_SIZE = 10;
public Integer currentPage {get; set;}
public Integer totalPage {get; set;}
private ApexPages.StandardSetController ssController;
public Boolean getEnablePrev(){
return ssController.getHasPrevious();
}
public Boolean getEnableNext(){
return ssController.getHasNext();
}
public void PagingCtrl(){
}
public PageReference searchinit() {
ssController = new ApexPages.StandardSetController([SELECT Id, Name FROM Account]);
currentPage = ssController.getPageNumber();
ssController.setPageSize(PAGE_SIZE);
totalPage = (Integer)Math.ceil((Decimal)ssController.getResultSize() / PAGE_SIZE);
return null;
}
public void next() {
ssController.next();
currentPage = ssController.getPageNumber();
}
public void prev() {
ssController.previous();
currentPage = ssController.getPageNumber();
}
public List<Account> getAccountList(){
return (List<Account>)ssController.getRecords();
}
}
Attempt to de-reference a null object
FATAL_ERROR Class.AccountListCon.getEnablePrev: line 292, column 1
public Boolean getEnablePrev(){
return ssController.getHasPrevious();
}
It looks like getEnablePrev() is being called prior to searchInit(), where ssController is initialized. Your Visualforce page may be attempting to render the pagination area prior to completing the initialization of the required data; we couldn't tell the reason why without seeing the relevant portions of your Visualforce page.

Azure AD B2C with Graph API - how to get/set user's email?

I add users to Azure AD B2C with Graph API but I don't get it how to store users' email (the primary one). Which field here is the user's primary email address?
As I read here on SO there's no way to populate values in Authentication contact info. It this correct?
Here's how I do it:
public async Task<AdUser> GetUserByObjectId(Guid objectId)
{
string userJson = await SendGraphGetRequest("/users/" + objectId, null);
JObject jUser = JObject.Parse(userJson);
return new AdUser(jUser);
}
internal AdUser(JObject jUser)
{
AccountEnabled = jUser["accountEnabled"].Value<bool>();
CompanyName = jUser["companyName"].Value<string>();
Department = jUser["department"].Value<string>();
DisplayName = jUser["displayName"].Value<string>();
FirstName = jUser["givenName"].Value<string>();
JobTitle = jUser["jobTitle"].Value<string>();
LastName = jUser["surname"].Value<string>();
MailNickname = jUser["mailNickname"].Value<string>();
Mobile = jUser["mobile"].Value<string>();
ObjectId = new Guid(jUser["objectId"].Value<string>());
List<string> mailList = new List<string>(jUser["otherMails"].Count());
mailList.AddRange(jUser["otherMails"].Select(mail => mail.Value<string>()));
OtherMails = mailList.AsReadOnly();
Phone = jUser["telephoneNumber"].Value<string>();
List<(string type, string value)> signInNames = jUser["signInNames"].Select(jToken => (jToken["type"].Value<string>(), jToken["value"].Value<string>())).ToList();
SignInNames = signInNames.AsReadOnly();
UserPrincipalName = jUser["userPrincipalName"].Value<string>();
UserType = jUser["userType"].Value<string>();
}
and here's the Email property of the AdUser:
public string Email
{
get
{
if (SignInNames.Count > 0 && SignInNames[0].type == "emailAddress")
return SignInNames[0].value;
if (OtherMails.Count > 0)
return OtherMails[0];
throw new InvalidOperationException("Don't know where to get user Email");
}
}
You need to make a PATCH request to the users endpoint
{baseurl}/{tenantId}/users?api-version={apiVersion}
Don't forget you access token in the auth header:
Authorization: Bearer {accessToken}
Here's an example model (Java) with methods for calculating and setting the sign-in email on a user object:
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.ArrayList;
import java.util.List;
#JsonIgnoreProperties(ignoreUnknown = true)
public class GraphApiUserExample{
#JsonProperty("objectId")
private String id;
private Boolean accountEnabled;
private PasswordProfile PasswordProfile;
private List<SignInName> signInNames;
private String surname;
private String displayName;
private String givenName;
#JsonProperty("userPrincipalName")
private String userPrincipalName;
public String getId(){
return id;
}
public void setId(final String id){
this.id = id;
}
public Boolean getAccountEnabled(){
return accountEnabled;
}
public void setAccountEnabled(final Boolean accountEnabled){
this.accountEnabled = accountEnabled;
}
public PasswordProfile getPasswordProfile(){
return passwordProfile;
}
public void setPasswordProfile(final PasswordProfile passwordProfile){
this.passwordProfile = passwordProfile;
}
public List<SignInName> getSignInNames(){
return signInNames;
}
public void setSignInNames(final List<SignInName> signInNames){
this.signInNames = signInNames;
}
public String getSurname(){
return surname;
}
public void setSurname(final String surname){
this.surname = surname;
}
public String getDisplayName(){
return displayName;
}
public void setDisplayName(final String displayName){
this.displayName = displayName;
}
public String getGivenName(){
return givenName;
}
public void setGivenName(final String givenName){
this.givenName = givenName;
}
public String getUserPrincipalName(){
return userPrincipalName;
}
public void setUserPrincipalName(final String userPrincipalName){
this.userPrincipalName = userPrincipalName;
}
#JsonIgnore
public String getSignInEmail(){
String email = "";
if(signInNames != null){
for(SignInName signInName : signInNames){
if(signInName.getType().equals("emailAddress")){
email = signInName.getValue();
break;
}
}
}
return email;
}
#JsonIgnore
public void setSignInEmail(String signInEmail){
if(signInNames == null){
signInNames = new ArrayList<>();
signInNames.add(new SignInName("emailAddress", signInEmail));
return;
}
for(SignInName signInName : signInNames){
if(signInName.getType().equals("emailAddress")){
signInName.setValue(signInEmail);
break;
}
}
}
}
SignInName:
public class SignInName {//userName or emailAddress
private String
type,
value;
public String getType(){
return type;
}
public void setType(final String type){
this.type = type;
}
public String getValue(){
return value;
}
public void setValue(final String value){
this.value = value;
}
}
PasswordProfile:
#JsonIgnoreProperties(ignoreUnknown = true)
public class PasswordProfile {
private String password;
private Boolean forceChangePasswordNextLogin;
public String getPassword(){
return password;
}
public void setPassword(final String password){
this.password = password;
}
public Boolean getForceChangePasswordNextLogin(){
return forceChangePasswordNextLogin;
}
public void setForceChangePasswordNextLogin(final Boolean forceChangePasswordNextLogin){
this.forceChangePasswordNextLogin = forceChangePasswordNextLogin;
}
}

JavaFX - How do I access the result(ObservableList) from a service?

How do I access the returned result from a service? The result is queried from the database and added to a ObservableList. I have a checkbox and wanted its value to depend on the result from the database.
How do I bind the checkbox so that its value(checked/unchecked) will depend on the rs.getString("studentForm137") field.
//cboxForm137.selectedProperty().bind(//I don't know the codes to bind checkbox);
Service
final Service<ObservableList<Student>> service = new Service<ObservableList<Student>>()
{
#Override
protected Task<ObservableList<Student>> createTask()
{
return new Task<ObservableList<Student>>()
{
#Override
protected ObservableList<Student> call() throws Exception
{
for (int i = 0; i < 250; i++)
{
updateProgress(i, 250);
Thread.sleep(2);
}
return student.display();
}
};
}
};
service.start();
Student Class
public class Student extends Person {
private SimpleStringProperty form137;
private SimpleStringProperty form138;
private SimpleStringProperty goodMoralCertificate;
private SimpleStringProperty birthCertificate;
private SimpleStringProperty highschoolDiploma;
public Student()
{
super();
}
public Student(String lastName, String firstName, String middleName,
String cpNumber, String address, String dateOfBirth,
String placeOfBirth, String emailAddress, String gender,
String fathersName, String mothersName,
String form137, String form138, String goodMoralCertificate,
String birthCertificate, String highschoolDiploma)
{
super(lastName, firstName, middleName,
cpNumber, address, dateOfBirth, placeOfBirth, emailAddress, gender,
fathersName, mothersName);
this.form137 = new SimpleStringProperty(form137);
this.form138 = new SimpleStringProperty(form138);
this.goodMoralCertificate = new SimpleStringProperty(goodMoralCertificate);
this.birthCertificate = new SimpleStringProperty(birthCertificate);
this.highschoolDiploma = new SimpleStringProperty(highschoolDiploma);
}
//form137
public String getForm137()
{
return form137.get();
}
public void setForm137(String form137)
{
this.form137.set(form137);
}
public StringProperty form137Property()
{
return form137;
}
//form138
public String getForm138()
{
return form138.get();
}
public void setForm138(String form138)
{
this.form138.set(form138);
}
public StringProperty form138Property()
{
return form138;
}
//goodMoralCertificate
public String getGoodMoralCertificate()
{
return goodMoralCertificate.get();
}
public void setGoodMoralCertificate(String goodMoralCertificate)
{
this.goodMoralCertificate.set(goodMoralCertificate);
}
public StringProperty goodMoralCertificateProperty()
{
return goodMoralCertificate;
}
//birthCertificate
public String getBirthCertificate()
{
return birthCertificate.get();
}
public void setBirthCertificate(String birthCertificate)
{
this.birthCertificate.set(birthCertificate);
}
public StringProperty birthCertificateProperty()
{
return birthCertificate;
}
//highschoolDiploma
public String getHighschoolDiploma()
{
return highschoolDiploma.get();
}
public void setHighschoolDiploma(String highschoolDiploma)
{
this.highschoolDiploma.set(highschoolDiploma);
}
public StringProperty highschoolDiplomaProperty()
{
return highschoolDiploma;
}
#Override
public ObservableList display()
{
Connection c = null;
PreparedStatement pst = null;
ResultSet rs = null;
ObservableList<Student> student = FXCollections.observableArrayList();
try
{
c = MySqlConnection.connect();
String SQL = "SELECT * " +
"FROM students ";
pst = c.prepareStatement(SQL);
rs = pst.executeQuery();
while(rs.next())
{
student.add(new Student(rs.getString("studentLastName"),
rs.getString("studentFirstName"),
rs.getString("studentMiddleName"),
rs.getString("studentCPNumber"),
rs.getString("studentAddress"),
rs.getString("studentDateOfBirth"),
rs.getString("studentPlaceOfBirth"),
rs.getString("studentEmailAddress"),
rs.getString("studentGender"),
rs.getString("studentFathersName"),
rs.getString("studentMothersName"),
rs.getString("studentForm137"),
rs.getString("studentForm138"),
rs.getString("studentGMC"),
rs.getString("studentNSO"),
rs.getString("studentHSDiploma")));
}
}
catch(Exception e)
{
System.out.println("Error on Building Data");
}
finally
{
try
{
PublicClass.closeConnection(c, pst, rs);
}
catch (SQLException ex)
{
Logger.getLogger(Student.class.getName()).log(Level.SEVERE, null, ex);
}
}
return student;
}
}

Resources