I am trying to set a logIn/signUp to a google account. I wrote the code and it should work but it doesn't(it always ends up with the failed toast I made).
I watch a bunch of videos and looked at google doc and my code is pretty much the same.
protected void onStart() {
if( getIntent().getBooleanExtra(ThirdActivity.extraLoggedIn, false) == false ) {
GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
if (account != null) {
getDataFromFirebase(account);
//playerNameText.setText("Player Name: " + accountName);
} else {
startActivityForResult(mGoogleSignInClient.getSignInIntent(), 0);
//account = GoogleSignIn.getLastSignedInAccount(this);
//signUp(account);
}
loggedIn = true;
}
super.onStart();
changeLanguage(SingletonDemiClass.getInstance().getLanguage());
playerNameText.setText("Player Name: " + accountName);
}
#Override
public void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 0){
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
//Toast.makeText(SecondActivity.this, task.getResult().getId(), Toast.LENGTH_LONG).show();
signUp(task);
}
}
//private void signUp(GoogleSignInAccount account) {
private void signUp(Task<GoogleSignInAccount> completedTask) {
try {
GoogleSignInAccount account = completedTask.getResult(ApiException.class);
accountID = account.getId();
accountName = account.getDisplayName();
}
catch (ApiException ex) {
Log.w("Google Sign-In Error", "signInResult:failed code=" + ex.getStatusCode());
Toast.makeText(SecondActivity.this, "Failed", Toast.LENGTH_LONG).show();
//}
}
}
Logcat
Related
Currently i'm implementing the in app update feature from android. I'm using the immediate update method, the problem that I'm facing is that when the UI prompting the user to update shows and the user does not click the update button instead they click the cross button. The UI for the app update just closes and user can continue using the app.
What I want is that when user click the cross button the app immediately closes, until user updates the app then they can use the app as usual. I also uses the java code for the android development.
public class LoginActivity extends AppCompatActivity {
private LoginViewModel loginViewModel;
public static final String MyPREFERENCES = "LoginPrefs" ;
public static final String Name = "nameKey";
public static final String User = "userKey";
public static final String con = "closed";
public static String error = "";
public static int userFlag = 0;
SharedPreferences sharedpreferences;
SharedPreferences.Editor editor;
public TextInputEditText usernameEditText;
public TextInputEditText passwordEditText;
private AppUpdateManager mAppUpdateManager;
private int RC_APP_UPDATE = 999;
private int inAppUpdateType;
private com.google.android.play.core.tasks.Task<AppUpdateInfo> appUpdateInfoTask;
private InstallStateUpdatedListener installStateUpdatedListener;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
loginViewModel = ViewModelProviders.of(this, new LoginViewModelFactory())
.get(LoginViewModel.class);
usernameEditText = findViewById(R.id.user);
passwordEditText = findViewById(R.id.pass);
final Button loginButton = findViewById(R.id.submitBTN);
final TextInputLayout userL = findViewById(R.id.userL);
final TextInputLayout passL = findViewById(R.id.passL);
final JellyToggleButton jtb = findViewById(R.id.jtb);
// Creates instance of the manager.
mAppUpdateManager = AppUpdateManagerFactory.create(this);
// Returns an intent object that you use to check for an update.
appUpdateInfoTask = mAppUpdateManager.getAppUpdateInfo();
//lambda operation used for below listener
//For flexible update
installStateUpdatedListener = installState -> {
if (installState.installStatus() == InstallStatus.DOWNLOADED) {
popupSnackbarForCompleteUpdate();
}
};
mAppUpdateManager.registerListener(installStateUpdatedListener);
inAppUpdateType = AppUpdateType.IMMEDIATE; //1
inAppUpdate();
if(userFlag==1){
jtb.setChecked(true);
}
userL.setHint("Enter username");
sharedpreferences = getSharedPreferences(MyPREFERENCES, MODE_PRIVATE);
loginViewModel.getLoginFormState().observe(this, new Observer<LoginFormState>() {
#Override
public void onChanged(#Nullable LoginFormState loginFormState) {
if (loginFormState == null) {
return;
}
loginButton.setEnabled(loginFormState.isDataValid());
if (loginFormState.getUsernameError() != null) {
usernameEditText.setError(getString(loginFormState.getUsernameError()));
loginButton.startAnimation(AnimationUtils.loadAnimation(LoginActivity.this,R.anim.shake));
}
if (loginFormState.getPasswordError() != null) {
passwordEditText.setError(getString(loginFormState.getPasswordError()));
loginButton.startAnimation(AnimationUtils.loadAnimation(LoginActivity.this,R.anim.shake));
}
}
});
loginViewModel.getLoginResult().observe(this, new Observer<LoginResult>() {
#Override
public void onChanged(#Nullable LoginResult loginResult) {
if (loginResult == null) {
return;
}
if (loginResult.getError() != null) {
showLoginFailed(loginResult.getError());
}
if (loginResult.getSuccess() != null) {
updateUiWithUser(loginResult.getSuccess());
Intent i = new Intent(LoginActivity.this, user_dashboard.class);
startActivity(i);
}
setResult(Activity.RESULT_OK);
//Complete and destroy login activity once successful
}
});
TextWatcher afterTextChangedListener = new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// ignore
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// ignore
}
#Override
public void afterTextChanged(Editable s) {
loginViewModel.loginDataChanged(usernameEditText.getText().toString(),
passwordEditText.getText().toString());
}
};
usernameEditText.addTextChangedListener(afterTextChangedListener);
passwordEditText.addTextChangedListener(afterTextChangedListener);
passwordEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
loginViewModel.login(usernameEditText.getText().toString(),
passwordEditText.getText().toString());
}
return false;
}
});
loginButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(userFlag==0) {
loginViewModel.login(usernameEditText.getText().toString(),
passwordEditText.getText().toString());
getStaffData();
}
else if(userFlag==1){
loginWorker();
}
}
});
jtb.setOnStateChangeListener(new JellyToggleButton.OnStateChangeListener() {
#Override
public void onStateChange(float process, State state, JellyToggleButton jtb) {
if (state.equals(State.LEFT)) {
userL.setHint("Enter username");
error = "Username cannot be empty";
userFlag = 0;
}
if (state.equals(State.RIGHT)) {
userL.setHint("Enter badge ID");
error = "Badge ID cannot be empty";
userFlag = 1;
}
}
});
}
#Override
protected void onDestroy() {
mAppUpdateManager.unregisterListener(installStateUpdatedListener);
finishAndRemoveTask();
super.onDestroy();
}
#Override
protected void onResume() {
try {
mAppUpdateManager.getAppUpdateInfo().addOnSuccessListener(appUpdateInfo -> {
if (appUpdateInfo.updateAvailability() ==
UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS) {
// If an in-app update is already running, resume the update.
try {
mAppUpdateManager.startUpdateFlowForResult(
appUpdateInfo,
inAppUpdateType,
this,
RC_APP_UPDATE);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
}
});
mAppUpdateManager.getAppUpdateInfo().addOnSuccessListener(appUpdateInfo -> {
//For flexible update
if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) {
popupSnackbarForCompleteUpdate();
}
});
} catch (Exception e) {
e.printStackTrace();
}
super.onResume();
}
#Override //For flexible update
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_APP_UPDATE) {
//when user clicks update button
if (resultCode == RESULT_OK) {
Toast.makeText(LoginActivity.this, "App download starts...", Toast.LENGTH_LONG).show();
} else if (resultCode == RESULT_CANCELED) {
//if you want to request the update again just call checkUpdate()
Toast.makeText(LoginActivity.this, "App download canceled.", Toast.LENGTH_LONG).show();
} else if (resultCode == RESULT_IN_APP_UPDATE_FAILED) {
Toast.makeText(LoginActivity.this, "App download failed.", Toast.LENGTH_LONG).show();
}
}
}
private void updateUiWithUser(LoggedInUserView model) {
String welcome = getString(R.string.welcome);
// TODO : initiate successful logged in experience
Toast.makeText(getApplicationContext(), welcome, Toast.LENGTH_LONG).show();
}
private void showLoginFailed(#StringRes Integer errorString) {
Toast.makeText(getApplicationContext(), errorString, Toast.LENGTH_SHORT).show();
}
private void getStaffData() {
String username = usernameEditText.getText().toString();
APIInterface apiInterface3 = APIClient.getClient().create(APIInterface.class);
Call<loginList> call3 = apiInterface3.staffData(username);
call3.enqueue(new Callback<loginList>() {
#Override
public void onResponse(Call<loginList> call, Response<loginList> response) {
loginList list = response.body();
if (list!=null && list.getStatusCode()==1) { //response received.
if(list.getStaffList().size()>0){
Log.d("check-in", list.getStatusCode() + " " + list.getStaffList().get(0).getName());
Toast.makeText(LoginActivity.this,"Logged in",Toast.LENGTH_SHORT).show();
final String name = list.getStaffList().get(0).getName();
final String badge = list.getStaffList().get(0).getBadge();
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Name,name);
editor.putString(User,badge);
editor.putInt(con,1);
editor.apply();
}
else if(list.getStaffList().size()==0){
}
}
}
#Override
public void onFailure(Call<loginList> call, Throwable t) {
Log.d("fail",t.toString());
}
});
}
private void loginWorker(){
String username = usernameEditText.getText().toString();
String password = passwordEditText.getText().toString();
APIInterface apiInterface3 = APIClient.getClient().create(APIInterface.class);
Call<loginList> call3 = apiInterface3.loginWorker(username,password);
call3.enqueue(new Callback<loginList>() {
#Override
public void onResponse(Call<loginList> call, Response<loginList> response) {
loginList list = response.body();
Log.d("response", response.body().toString());
if (list!=null && list.getStatusCode()==1) { //response received.
if(list.getLoginList().size()>0){
Log.d("check-in", list.getStatusCode() + " " + list.getLoginList().get(0).getName());
Toast.makeText(LoginActivity.this,"Logged in",Toast.LENGTH_SHORT).show();
List<login> item = response.body().getLoginList();
final String name = list.getLoginList().get(0).getName();
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Name,name);
editor.putInt(con,1);
editor.apply();
}
String welcome = getString(R.string.welcome);
Toast.makeText(getApplicationContext(), welcome, Toast.LENGTH_SHORT).show();
Intent i = new Intent(LoginActivity.this, user_dashboard.class);
startActivity(i);
}
else
Toast.makeText(LoginActivity.this, "wrong ID or password",Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(Call<loginList> call, Throwable t) {
Log.d("fail",t.toString());
}
});
editor = sharedpreferences.edit();
editor.putString(User, username);
editor.commit();
}
#Override
public void onBackPressed() {
new MaterialAlertDialogBuilder(LoginActivity.this,R.style.MyDialogTheme)
.setTitle("Exit")
.setMessage("Confirm to exit?")
.setBackground(getDrawable(R.drawable.alert_dialog))
// Specifying a listener allows you to take an action before dismissing the dialog.
// The dialog is automatically dismissed when a dialog button is clicked.
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Continue with delete
finishAffinity();
}
})
.setNegativeButton(android.R.string.no, null)
.show();
}
private void inAppUpdate() {
try {
// Checks that the platform will allow the specified type of update.
appUpdateInfoTask.addOnSuccessListener(new OnSuccessListener<AppUpdateInfo>() {
#Override
public void onSuccess(AppUpdateInfo appUpdateInfo) {
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
// For a flexible update, use AppUpdateType.FLEXIBLE
&& appUpdateInfo.isUpdateTypeAllowed(inAppUpdateType)) {
// Request the update.
try {
mAppUpdateManager.startUpdateFlowForResult(
// Pass the intent that is returned by 'getAppUpdateInfo()'.
appUpdateInfo,
// Or 'AppUpdateType.FLEXIBLE' for flexible updates.
inAppUpdateType,
// The current activity making the update request.
LoginActivity.this,
// Include a request code to later monitor this update request.
RC_APP_UPDATE);
} catch (IntentSender.SendIntentException ignored) {
}
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
private void popupSnackbarForCompleteUpdate() {
try {
Snackbar snackbar =
Snackbar.make(
findViewById(R.id.coordinatorL),
"An update has just been downloaded.\nRestart to update",
Snackbar.LENGTH_INDEFINITE);
snackbar.setAction("INSTALL", view -> {
if (mAppUpdateManager != null){
mAppUpdateManager.completeUpdate();
}
});
snackbar.setActionTextColor(getResources().getColor(R.color.orange));
snackbar.show();
} catch (Resources.NotFoundException e) {
e.printStackTrace();
}
}
}
The image I borrowed from google, on the left image as can be seen there is a cross button on top right user can click to close the update process
The most important point I will emphasize is that you should not force users to update the app until it is absolutely necessary (like some security issues etc). Forcing updates to users is considered a very bad user experience.
To the question you asked, you have the answer in your question itself. If you check the code you have something like this in your onActivityResult method-
if (requestCode == RC_APP_UPDATE) {
//when user clicks update button
if (resultCode == RESULT_OK) {
Toast.makeText(LoginActivity.this, "App download starts...", Toast.LENGTH_LONG).show();
} else if (resultCode == RESULT_CANCELED) {
//if you want to request the update again just call checkUpdate()
Toast.makeText(LoginActivity.this, "App download canceled.", Toast.LENGTH_LONG).show();
} else if (resultCode == RESULT_IN_APP_UPDATE_FAILED) {
Toast.makeText(LoginActivity.this, "App download failed.", Toast.LENGTH_LONG).show();
}
}
In case when the user cancels resultCode == RESULT_CANCELED or the update fails resultCode == RESULT_IN_APP_UPDATE_FAILED, you can take whatever action you want. You can finish the activity or whatever is suitable in your situation.
I've tried to implement silent sign-in as mentioned here
I've tried to restrict other domain login via regex, I don't know if any other method is out there, I've seen the 'hd' parameter in Firebase login, but implementation was unsuccessful.
Edit 1: Fixed code, now the silent sign-in doesn't work. Code is redundant, also GoogleApiClient is deprecate.
I've seen answers with SharedPreferences to save login token, but is it safe to save token?
I've followed the documentation here
MainActivity.java
mAuth = FirebaseAuth.getInstance();
if(mAuth.getCurrentUser() != null) {
silentLogin();
}
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build();
mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this, this)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
//Show sign-in and sign-out buttons
public void silentLogin() {
OptionalPendingResult<GoogleSignInResult> pendingResult =
Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient);
if (pendingResult != null) {
handleGooglePendingResult(pendingResult);
} else {
signIn();
}
}
private void handleGooglePendingResult(OptionalPendingResult<GoogleSignInResult> pendingResult) {
if (pendingResult.isDone()) {
GoogleSignInResult signInResult = pendingResult.get();
onSilentSignInCompleted(signInResult);
} else {
pendingResult.setResultCallback(new ResultCallback<GoogleSignInResult>() {
#Override
public void onResult(#NonNull GoogleSignInResult signInResult) {
onSilentSignInCompleted(signInResult);
}
});
}
}
private void onSilentSignInCompleted(GoogleSignInResult signInResult) {
GoogleSignInAccount signInAccount = signInResult.getSignInAccount();
if (signInAccount != null) {
//Show sign out button
}
else {
signIn();
}
}
private void signIn(){
Intent signInIntent = mGoogleSignInClient.getSignInIntent();
startActivityForResult(signInIntent, RC_SIGN_IN);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == RC_SIGN_IN){
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
handleSignInResult(task);
}
}
private void handleSignInResult(Task<GoogleSignInAccount> completedTask){
try{
GoogleSignInAccount acc = completedTask.getResult(ApiException.class);
FirebaseGoogleAuth(acc);
}
catch (ApiException e){
//Show error
FirebaseGoogleAuth(null);
}
}
private void FirebaseGoogleAuth(GoogleSignInAccount acct) {
if (acct != null) {
AuthCredential authCredential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
mAuth.signInWithCredential(authCredential).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
FirebaseUser user = mAuth.getCurrentUser();
updateUI(user);
} else {
updateUI(null);
}
}
});
}
else{
// Auth failed
}
}
private void updateUI(FirebaseUser fUser){
GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(getApplicationContext());
if(account != null){
String personName = account.getDisplayName();
String personEmail = account.getEmail();
if (personEmail != null) {
if(personEmail.endsWith("gmail.com"))
{
//Show details
}
else
{
mGoogleSignInClient.signOut();
Toast.makeText(MainActivity.this,"Login with gmail account only",Toast.LENGTH_SHORT).show();
//Show sign in button again
}
}
}
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
//Connection failed
}
}
Your mAuth is null because it's defined after you are doing the process with it.
mAuth = FirebaseAuth.getInstance(); line should be before that condition.
Do it as below:
mAuth = FirebaseAuth.getInstance();
if(mAuth.getCurrentUser() != null) {
silentLogin();
}
It will work for sure.
Edited:
What I have done in my project:
final GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(MyActivity.this);
if (account != null) {
gotoNextActivity();
} else {
signInButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
signIn();
}
});
}
After looking at the previous answer and reading a few documentations, I've come to conclusion as I've implemented the above in the following manner:
GoogleSignInOptions googleSignInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.requestIdToken(getString(R.string.default_web_client_id))
.build();
mGoogleSignInClient = GoogleSignIn.getClient(this, googleSignInOptions);
GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
updateUI(mAuth.getCurrentUser());
}
private void updateUI(FirebaseUser firebaseUser) {
if (firebaseUser != null) {
if(Objects.requireNonNull(firebaseUser.getEmail()).endsWith("gmail.com"))
{
//Display details of user
}
else
{
//Sign out
mGoogleSignInClient.revokeAccess();
updateUI(mAuth.getCurrentUser());
Toast.makeText(this, "Login with gmail address only!", Toast.LENGTH_SHORT).show();
}
}else{
// Show sign in button
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == SIGN_IN_REQUEST_CODE){
Task<GoogleSignInAccount> accountTask = GoogleSignIn.getSignedInAccountFromIntent(data);
handleGoogleSignIn(accountTask);
}
}
private void handleGoogleSignIn(Task<GoogleSignInAccount> accountTask) {
try {
GoogleSignInAccount account = accountTask.getResult(ApiException.class);
if (account != null) {
firebaseAuthWithGoogle(account);
}
}
}
private void firebaseAuthWithGoogle(GoogleSignInAccount account) {
AuthCredential credential = GoogleAuthProvider.getCredential(account.getIdToken(), null);
mAuth.signInWithCredential(credential)
.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
FirebaseUser user = mAuth.getCurrentUser();
updateUI(user);
} else {
// Show error
}
});
}
}
If there's a better approach, please comment.
Documentation referred:
1: Google Sign In
2: Firebase Google Sign In
I am using firebase auth UI (FirebaseUI-Android) in an android app, where the user can signup with personal email, Facebook, number and Gmail accounts. My question is I need to get email verification when user sign's up with his personal email id.
List<AuthUI.IdpConfig> providers = Arrays.asList(
new AuthUI.IdpConfig.Builder(AuthUI.EMAIL_PROVIDER).build(),
new AuthUI.IdpConfig.Builder(AuthUI.PHONE_VERIFICATION_PROVIDER).build(),
new AuthUI.IdpConfig.Builder(AuthUI.FACEBOOK_PROVIDER).build(),
new AuthUI.IdpConfig.Builder(AuthUI.GOOGLE_PROVIDER).build());
startActivityForResult(
AuthUI.getInstance()
.createSignInIntentBuilder()
.setIsSmartLockEnabled(true)
.setTheme(R.style.GreenTheme)
.setTosUrl("https://termsfeed.com/blog/terms-conditions-mobile-apps/")
.setPrivacyPolicyUrl("https://superapp.example.com/privacy-policy.html")
.setAvailableProviders(providers)
.build(),
RC_SIGN_IN);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// RC_SIGN_IN is the request code you passed into startActivityForResult(...) when starting the sign in flow.
if (requestCode == RC_SIGN_IN) {
IdpResponse response = IdpResponse.fromResultIntent(data);
// Successfully signed in
if (resultCode == RESULT_OK) {
startActivity(new Intent(Login.this,MainActivity.class));
finish();
return;
} else {
// Sign in failed
if (response == null) {
Toasty.error(getApplicationContext(),"Sign in cancelled",Toast.LENGTH_SHORT, true).show();
return;
}
if (response.getErrorCode() == ErrorCodes.NO_NETWORK) {
Toasty.error(getApplicationContext(),"No internet connection",Toast.LENGTH_SHORT, true).show();
return;
}
if (response.getErrorCode() == ErrorCodes.UNKNOWN_ERROR) {
Toasty.error(getApplicationContext(),"Unkown Error",Toast.LENGTH_SHORT, true).show();
return;
}
}
Toasty.error(getApplicationContext(),"Unknown sign in response",Toast.LENGTH_SHORT, true).show();
}
}
Here is my intent for sign up options.
You can simply do it as follows,
Get Current Firebase User Instance,
final FirebaseUser currentUser = mAuth.getCurrentUser();
Check if the provider is password indicating that the login method used is Email Auth,
if(null != currentUser) {
if("password".equals(currentUser.getProviderData().get(0).getProviderId())) {
/* Handle Verification */
}
}
Reference Link: https://firebase.google.com/docs/reference/android/com/google/firebase/auth/EmailAuthProvider#PROVIDER_ID
Check if user is already verified,
currentUser.isEmailVerified();
If user is not verified then the following code can be used to send a verification EMail,
if (!currentUser.isEmailVerified()) {
/* Do Something */
}
/* Send Verification Email */
currentUser.sendEmailVerification()
.addOnCompleteListener(this, new OnCompleteListener() {
#Override
public void onComplete(#NonNull Task task) {
/* Check Success */
if (task.isSuccessful()) {
Toast.makeText(getApplicationContext(),
"Verification Email Sent To: " + currentUser.getEmail(),
Toast.LENGTH_SHORT).show();
} else {
Log.e(TAG, "sendEmailVerification", task.getException());
Toast.makeText(getApplicationContext(),
"Failed To Send Verification Email!",
Toast.LENGTH_SHORT).show();
}
}
});
Once you have all the pieces in place, the final code snippet should look something like below:
Final Code Snippet:
if (requestCode == RC_SIGN_IN) {
IdpResponse response = IdpResponse.fromResultIntent(data);
/* Success */
if (resultCode == RESULT_OK) {
final FirebaseUser currentUser = mAuth.getCurrentUser();
if(null != currentUser) {
if("password".equals(currentUser.getProviderData().get(0).getProviderId())) {
if(!currentUser.isEmailVerified()) {
/* Send Verification Email */
currentUser.sendEmailVerification()
.addOnCompleteListener(this, new OnCompleteListener() {
#Override
public void onComplete(#NonNull Task task) {
/* Check Success */
if (task.isSuccessful()) {
Toast.makeText(getApplicationContext(),
"Verification Email Sent To: " + currentUser.getEmail(),
Toast.LENGTH_SHORT).show();
} else {
Log.e(TAG, "sendEmailVerification", task.getException());
Toast.makeText(getApplicationContext(),
"Failed To Send Verification Email!",
Toast.LENGTH_SHORT).show();
}
}
});
/* Handle Case When Email Not Verified */
}
}
/* Login Success */
startActivity(new Intent(Login.this, MainActivity.class));
finish();
return;
}
} else {
/* Handle Failure */
}
}
#user2004685 answer above gives very good hint. But it does not work at least for the latest firebase-ui because currentUser.getProviderData().get(0).getProviderId() returns 'firebase'.
So the updated solution is
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RC_SIGN_IN) {
IdpResponse response = IdpResponse.fromResultIntent(data);
/* Success */
if (resultCode == RESULT_OK) {
final FirebaseUser currentUser = mAuth.getCurrentUser();
if(null != currentUser) {
if(currentUser.getEmail()!=null) {
if(!currentUser.isEmailVerified()) {
/* Send Verification Email */
currentUser.sendEmailVerification()
.addOnCompleteListener(this, new OnCompleteListener() {
#Override
public void onComplete(#NonNull Task task) {
/* Check Success */
if (task.isSuccessful()) {
Toast.makeText(getApplicationContext(),
"Verification Email Sent To: " + currentUser.getEmail(),
Toast.LENGTH_SHORT).show();
} else {
Log.e(TAG, "sendEmailVerification", task.getException());
Toast.makeText(getApplicationContext(),
"Failed To Send Verification Email!",
Toast.LENGTH_SHORT).show();
}
}
});
/* Handle Case When Email Not Verified */
}
}
/* Login Success */
startActivity(new Intent(Login.this, MainActivity.class));
finish();
return;
}
} else {
/* Handle Failure */
}
}
}
simply replace if("password".equals(currentUser.getProviderData().get(0).getProviderId())) with if(currentUser.getEmail()!=null)
When integrating Google Play Games Sign-in, I needed to get the player name for my app, but the getCurrentPlayer() task never completed (playerName is perpetually null). OnActivityResult is ran from a startActivityForResult with the intent from the getSignInIntent() method of a GoogleSignInClient.
Here's the relevant code from onActivityResult (playerName is Global):
#Override public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Result returned from launching the Intent from signInClient
if (requestCode == SIGN_IN) {
Task<GoogleSignInAccount> resTask =
GoogleSignIn.getSignedInAccountFromIntent(data);
if (resTask.isSuccessful()) {
GoogleSignInAccount resAcct = resTask.getResult();
PlayersClient playersClient = Games.getPlayersClient(this, resAcct);
playersClient.getCurrentPlayer()
.addOnSuccessListener(new OnSuccessListener<Player>() {
#Override
public void onSuccess(Player taskPlayer) {
playerName = taskPlayer.getName();
}
});
while(playerName==null){
Log.d("OH GOD WHY", "WHY???");
}
//Do something with the name
...
} else {
Toast.makeText(getApplicationContext(), "Unable to sign in. Please try again later.", Toast.LENGTH_SHORT).show();
}
}
}
Before using OnSuccess, I was using OnComplete, but that never ran either (the isSuccessful() check never ran here):
playersClient.getCurrentPlayer()
.addOnCompleteListener(new OnCompleteListener<Player>() {
#Override
public void onComplete(Task<Player> pTask) {
if(pTask.isSuccessful()){
Player player = pTask.getResult();
playerName = player.getName();
} else {
//Handle error
...
}
}
});
I am trying to get e-mail address of the people the user has invited from my app
This is my code:
private void onInviteClicked() {
Intent intent = new AppInviteInvitation.IntentBuilder(getString(R.string.invitation_title))
.setMessage(getString(R.string.invitation_message))
.setDeepLink(Uri.parse(getString(R.string.invitation_deep_link)))
.setCustomImage(Uri.parse("http://jennstrends.com/wp-content/uploads/2013/10/bad-profile-pic-2.jpeg"))
.setCallToActionText(getString(R.string.invitation_cta)).setCallToActionText("email").build();
startActivityForResult(intent, REQUEST_INVITE);
}
int REQUEST_INVITE = 10101;
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d(TAG, "onActivityResult: requestCode=" + requestCode + ", resultCode=" + resultCode);
if (requestCode == REQUEST_INVITE) {
if (resultCode == RESULT_OK) {
// Get the invitation IDs of all sent messages
final String[] ids = AppInviteInvitation.getInvitationIds(resultCode, data);
final List<String> members = new ArrayList();
members.add(GoogleAuthHelper.getInstance().getUser().getProjectId());
for (String id : ids) {
members.add(id);
}
ApiClient.getInstance(getBaseContext()).addMembers(members, new OnPostListener<String>() {
#Override
public void onError(ANError error) {
Log.e("Server", "Members: " + error.getErrorCode());
}
#Override
public void onResponse(String val) {
Log.d("Server", "Response from Member: " + val.toString());
}
});
} else {
// Sending failed or it was canceled, show failure message to
// the user
// ...
Log.d("Server", "Invitation Failed code: " + resultCode);
}
}
}
Now how do I get the email addresses of the list of people the user has invited. AppInviteInvitation.getInvitationIds() are not the email ids. Someone help me out! Please!