When using Firebase Google user authentication the user is immediately logged in if they have already authorized the application and only logged in to one Google account.
Is there a way to force the "Choose an account" dialog to appear so that the user has the opportunity to login to a different Google account or create a new one?
Currency as far as I know the user has to manually logout of the current Google account (or login to > 1) from Google.com to make the dialog appear.
You can force to choose an account with 'prompt' provider parameter.
var googleAuthProvider = new firebase.auth.GoogleAuthProvider();
googleAuthProvider.setCustomParameters({
prompt: 'select_account'
});
firebase.auth().signInWithRedirect(googleAuthProvider)
Tested with Firebase JavaScript SDK v4.1.2
You should sign out from Google explicitly:
Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(status -> {
mFirebaseAuth.signOut();
});
Found the solution here
I'm trying to figure out the same thing. According to some Google documentation, it appears that you can force the account chooser with a "prompt" command (of "none", "select_account" or "consent"):
Force google account chooser
...however there appears to be no way to set the "prompt" value in any of Firebase's authentication methods (specifically authWithOAuthRedirect and authWithOAuthPopup).
Were you ever able to figure it out?
In my following code, the gooogle sign-in button every time prompts for choosing account...
public class MainActivity extends AppCompatActivity {
Button btn_signOut;
private GoogleSignInClient mGoogleSignInClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_signOut = findViewById(R.id.btnSignOut);
btn_signOut.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
signOut();
}
});
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build();
mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
}
private void signOut() {
mGoogleSignInClient.signOut()
.addOnCompleteListener(this, new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
finish();
}
});
}
}
Use this way to signout.
Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(new
ResultCallback<Status>()
{
#Override
public void onResult(#NonNull Status status)
{
mAuth.signOut();
}
});
In flutter, use: GoogleSignIn().signOut();
(assumming you used the google_sign_in package)
Related
I have a question. Can we add a invite button to the mobile app in android studio which on clicking gives referral link of the website instead of the application itself? Can we use firebase dynamic link for this or is it only to refer app itself?
I have added the code for dynamic link but its only to refer mobile app and not the website. I'd like to know if we can refer website as well.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_refer);
invite = findViewById(R.id.inviteBtn);
// calling the action bar
ActionBar actionBar = getSupportActionBar();
// showing the back button in action bar
actionBar.setDisplayHomeAsUpEnabled(true);
invite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
inviteLink();
}
});
}
public void inviteLink(){
Log.e("main", "invite link");
DynamicLink dynamicLink = FirebaseDynamicLinks.getInstance().createDynamicLink()
.setLink(Uri.parse("https://www.versatileva.com.au/"))
.setDomainUriPrefix("versatileva.page.link")
.setAndroidParameters(new DynamicLink.AndroidParameters.Builder().build())
.setIosParameters(new DynamicLink.IosParameters.Builder("com.android.versatilevaproject").build())
.buildDynamicLink();
Uri dynamicLinkUri = dynamicLink.getUri();
Log.e("main", " Long refer "+ dynamicLink.getUri());
//versatileva.page.link?apn=com.android.versatilevaproject&ibi=com.android.versatilevaproject&link=https%3A%2F%2Fwww.versatileva.com.au%2F
}
}
Firebase provide this guide on rewarding user referrals using Dynamic Links. You can use Dynamic Links along with Realtime Database and Cloud Functions for Firebase to encourage your users to invite their friends by offering in-app rewards for successful referrals to both the referrer and the recipient.
I am currently trying to build a new app (complete Novice) I have run into a strange issue on the login page.The sign up process works fine connects to firebase and returns to the login screen, then allows you to login and goes to the next activity. The problem occurs when you reload the app and use the details to re-login the login button does not work until you go into the sign up activity and come out of it then the login button works fine and allows you to sign in.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
Button button = findViewById(R.id.signupbtn);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
openSignupActivity();
}
});
}
private void openSignupActivity() {
Intent intent = new Intent(LoginActivity.this, SignupActivity.class);
startActivity(intent);
setContentView(R.layout.activity_login);
LoginEmail = findViewById(R.id.LoginEmail);
LoginPassword = findViewById(R.id.LoginPassword);
Loginprogressbar = findViewById(R.id.Loginprogressbar);
mAuth = FirebaseAuth.getInstance();
findViewById(R.id.Loginbtn).setOnClickListener(this);
if conditions between
if(task.isSuccessful()){
Toast.makeText(getApplicationContext(),"Login Successful",Toast.LENGTH_SHORT).show();
finish();
startActivity(new Intent(LoginActivity.this,MainActivity.class));
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.Loginbtn:
Loginuser();
break;`enter code here`
I am trying to use Google Sign-In for my android app from here.
I am able to log-in succesfully with the google account & able to fetch all the details. However, when ever I try to logout it fails with following error :
java.lang.IllegalStateException: GoogleApiClient is not connected yet.
I have read many answers suggesting to create googleClientApi object inside onCreate() and that's what I am doing.I have added callbacks for connected and suspended but the connect never goes into suspended mode.
Following is my code snippet :
public static void doInit(Context ctx, FragmentActivity fragmentActivity) {
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(
GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build();
mGoogleApiClient = new GoogleApiClient.Builder(ctx)
.enableAutoManage(fragmentActivity , googleAuth)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.addConnectionCallbacks(googleAuth)
.build();
}
public static Intent doGoogleLogIn() {
return Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
}
public static boolean doGoogleLogOut() {
Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
}
});
return true;
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
// An unresolvable error has occurred and Google APIs (including Sign-In) will not
// be available.
Log.d("Signin", "onConnectionFailed:" + connectionResult);
}
#Override
public void onConnected(#Nullable Bundle bundle) {
System.out.println("Connected...");
}
#Override
public void onConnectionSuspended(int i) {
System.out.println("Suspened....");
}
The only thing that is doubtful to me is, when I login and create googleApiClient object, its created from different activity that the one which I am using for logout. I don't suspect this is the reason because when the activity loaded, the isConnected on googleApiClient is returning true. However, the moment I do some UI action(Click on Logout), it starts returning false.
Primary requirement was to login and logout from different activities.
Finally I managed to make it work.
The actual cause of the error is "enableAutoManage" invocation at the time of Building Client object.
The API doc here suggests that it would automatically do the life cycle management by calling methods on onStart & onStop of the activity.
Therefore, if you want to use the same object across different activities then you should avoid calling "enableAutoManage" and invoke apiObject.connect(preferably in onStart of activity) and apiObject.disconnect() or logout (preferably in onStop of activity) manually.
Thank to Firebase the user can logged with the help of G+, Facebook or Twitter. When they are logged, everything is fine.
When the Android app is closed and re-opened, how to reenable the previous succeed logged user with the Firebase API. It is not explained neither in the app demo or in the documentation.
For exemple for Facebook, the sdk seems to save the token, that 's why the button is at connected state (showing that you can disconnect). But what about Firebase and for other authentication systems.
Thanks to the #Frank-van-Puffelen answer, I had some trials until I get something relevant (at least for me : comment are welcome to improve).
I have based my OAuth architecture into 3 mains components :
fdsfds
One single AuthStateListener that is located in the Application.
One Utils Singleton OAuthManager that deal with all authentication process
One or Many Activities that deals with Authentification user interaction (Signin Buttons and so on)
Application Class
FacebookSdk.sdkInitialize(this);
Firebase.setAndroidContext(this);
Firebase.getDefaultConfig().setLogLevel(Logger.Level.DEBUG);
Firebase.getDefaultConfig().setPersistenceEnabled(true);
Firebase ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
ref.addAuthStateListener(new Firebase.AuthStateListener() {
#Override
public void onAuthStateChanged(AuthData authData) {
if (authData != null) {
// user is logged in
// create a partialUser from authData
OAuthManager.getDefault().setAuthenticatedUser(authData);
// fetch, merge and save back the partialUser with server registerUser.
OAuthManager.getDefault().startFetchingUserInfo();
} else {
// user is not logged in
// Try to retrieve the user from Facebook SDK
// Try to retrieve the user from "Token and Id save in Android Preferences (in case of issue, or cache reset from Firebase))
// In retrieve is not possible, clean auth data
OAuthManager.getDefault().retrieveOAuth(MilleZimU.getInstance());
}
}
});
OAuthManager
Here is every services that deal with authentication (part has been copy from the Firebase dedicated demo activity)
SignInActivity
Here only remain the part that deal with UI interaction.
Retreiving ?
I'm not sure this is necessary, but case to case (maybe due to crash or update of the app), authentication status where different from Firebase|Prefs|FacebookSdk. I will see with time.
You'll need to add a AuthStateListener. This is described in the Firebase documentation on Monitoring Authentication. From there:
Firebase ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
ref.addAuthStateListener(new Firebase.AuthStateListener() {
#Override
public void onAuthStateChanged(AuthData authData) {
if (authData != null) {
// user is logged in
} else {
// user is not logged in
}
}
});
For anything related to Firebase Authentication on Android, the dedicated demo app is a great next stop. But be sure to first read the documentation, they're not half bad as far as docs go.
Create a BaseActivity class and make sure all other Activities in the app extends that class. The use 'instanceOf' to send user to LoginActivity if authData is null from AuthListener.
package com.mabiri.mabiristores;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.firebase.client.AuthData;
import com.firebase.client.Firebase;
import com.mabiri.mabiristores.login.CreateAccount2Activity;
import com.mabiri.mabiristores.login.CreateAccountActivity;
import com.mabiri.mabiristores.login.LoginActivity;
import com.mabiri.mabiristores.login.MapsActivity;
import com.mabiri.mabiristores.utils.Utils;
public class BaseActivity extends AppCompatActivity {
protected Firebase.AuthStateListener mAuthListener;
protected Firebase mFirebaseRef;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mFirebaseRef = new Firebase(YOUR_FIREBASE_URL);
if (!((this instanceof LoginActivity) || (this instanceof CreateAccountActivity)
|| (this instanceof CreateAccount2Activity) || (this instanceof MapsActivity))) {
mAuthListener = new Firebase.AuthStateListener() {
#Override
public void onAuthStateChanged(AuthData authData) {
/* The user has been logged out */
if (authData == null) {
//Stop services and clear sharedPreferences if any
/*Take user to login screen*/
takeUserToLoginScreenOnUnAuth();
}
}
};
mFirebaseRef.addAuthStateListener(mAuthListener);
}
}
#Override
protected void onResume() {
super.onResume();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
super.onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
/* Inflate the menu; this adds items to the action bar if it is present. */
getMenuInflater().inflate(R.menu.menu_base, menu);
return true;
}
private void takeUserToLoginScreenOnUnAuth() {
/** Move user to LoginActivity, and remove the backstack */
Intent intent = new Intent(BaseActivity.this, LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();
}
protected void logout() {
/**Unauthenticate user from firebase*/
mFirebaseRef.unauth();
}
/**
* Show error toast to users
*/
protected void showErrorToast(Context context, String message) {
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
}
}
Yup I have struggle with this as well, but a quick update on this issue, you cannot use the (and please correct me if i'm wrong):
Firebase ref
anymore, what you should do is declare as a global
private FirebaseAuth mAuth;
and then use this object on the listener:
mAuth = FirebaseAuth.getInstance();
and only after that you can use the listener
mAuth.addAuthStateListener(mAuthListener);
The push notification clears when the user taps on the notification to open app. However if the user goes and opens the app, the push notification is still there. How can I get rid of the notification? I can't seem to find anywhere in the documentation that addresses this.
Thanks a lot in advance
I did some digging as I too had this problem, and it looks like a bug in the Push Plugin. Basically they added the removal code to the pause event instead of the resume event.
You just have to change the code in src/android/com/plugin/gcm/PushPlugin.java
from:
#Override
public void onPause(boolean multitasking) {
super.onPause(multitasking);
gForeground = false;
final NotificationManager notificationManager = (NotificationManager) cordova.getActivity().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancelAll();
}
#Override
public void onResume(boolean multitasking) {
super.onResume(multitasking);
gForeground = true;
}
to:
#Override
public void onPause(boolean multitasking) {
super.onPause(multitasking);
gForeground = false;
}
#Override
public void onResume(boolean multitasking) {
super.onResume(multitasking);
gForeground = true;
final NotificationManager notificationManager = (NotificationManager) cordova.getActivity().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancelAll();
}
This will create a more standard behaviour, where the notifications will be removed on app resume (instead of on pause). Note though, I haven't fully tested the effects on the internal app messages yet, which may require more changes.