How to execute PendingIntent manually? - java

I show a notification and user navigates to a certain fragment when clicked on that notification.
fun showNotification() {
val pendingIntent = NavDeepLinkBuilder(this)
.setGraph(R.navigation.nav_graph)
.setDestination(R.id.fragment)
.createPendingIntent()
...
}
It does navigate correctly. However before navigating, I also want to check whether the user is logged in or not. The problem is that I can't check it because pendingIntent gets triggered as soon as I click on the notification. Is there a way for me to control before it gets executed?
I want something like this
if (isLoggedIn) pendingIntent.execute()
else navigateToLoginPage()
I tried overriding onNewIntent function however it didn't trigger at all.

your code is correct but your logic is not.
you have to navigate your user to an auth fragment in both cases.
and then if the user is logged in you can navigate him/her to his own home fragment or where ever u want, but if he/she is not logged it you can notify him/her

Related

How do I repeatedly check if the user is verified in the Firebase Authentication?

I want the program to repeatedly check if the user is verified in the Firebase Authentification until it is. For example, when the user makes an account on my application, the program switches into a new activity, waits until the user is verified, then automatically continues into the next activity.
I attempted to do this using a do while loop, but unfortunately, the program freezes and stays at a black screen. I never encountered any error messages along the way.
I tried the program with these lines of code:
EmailVerified = false;
do {
if (mAuth.getCurrentUser().isEmailVerified()) {
EmailVerified = true;
Intent intent = new Intent(VerificationEmailPage.this, MainActivity.class);
startActivity(intent);
}
} while (!EmailVerified);
Doing this caused the activity not to load, and simply turn black. It seemed as if no other code was also executed in the activity. I needed the activity to load and constantly keep checking if the user is verified, then switch to the next activity once it was.
What you're doing now is not a good idea at all. Instead, you should be using an AuthStateListener to find out when the user is signed in.
mAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
// Sign in logic here.
}
}
};
// activate it:
FirebaseAuth.getInstance().addAuthStateListener(mAuthListener);
// deactivate it:
FirebaseAuth.getInstance().removeAuthStateListener(mAuthListener);
The listener will get invoked any time the user is signed in or out, until the listener is removed.
Read more about how it works: How does the firebase AuthStateListener work?
Building upon Doug's answer, this is the best method for doing what you want:
Log in user (whether by sign in or creating an account).
Start a "loading" activity, this activity gets the current user using a FirebaseAuth.AuthStateListener.
In the onAuthStateChanged handler, check firebaseAuth.getCurrentUser().isEmailVerified().
If the user is verified, send them to the next activity.
If not, show a UI that asks the user to send a verification email.
When the user presses the send button, send a verification email configured to point back to your application (see Passing State in Email Actions).
When the user hits the URL from the verification email, check their isEmailVerified() state again.
Jump back to step 4.

Finish multiple activities on an authentication flow android

So I have an app that has authentication on it
here is the flow:
LoginPage -> Register -> RegisterConfirmation -> OTP Code -> EmailVerification -> Homepage
I want that if the user is already on OTP Code or Email Verification and he pressed the back button, the user will get straight to Homepage because he already got the AccessToken since RegisterConfirmation.
Here's the flow I want to look like:
How can I possible does this, I've already done some research but all I got is only how to finish only one activity (parent)?
Don't let the user go to OTP Code and check in registerconfirmation activity if the user already obtained his token access.
If you try to start an activity say A and you are in the current activity say D, you can use this with your intent :
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
To clear top activities (B,C,D)
EDIT:
You can keep the current instance of your activity using
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
When the user presses Back button do the below on onBackPressed() method. This might solve your problem. What it does is it clears the previous task and creates a new task
with the only activity in stack.
val intent = Intent(this,HomeActivity::class.java).apply{
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
}
startActivity(intent)
finish()

How do I override onBackPressed to ensure a logged out user cannot "go back" to MainActivity, and a logged in user cannot "go back" to SignInActivity?

Background: I have a SignInUserActivity and a MainActivity. The SignInUserActivity is first presented to the user when the user has not signed in or the auth token expired. On successful login, the user is directed to MainActivity, or if the auth token is valid on open of app the user will directed to MainActivity when the user opens the app. The user can sign out from MainActivity which will direct the user back to SignInUserActivity.
1) User signs in from SignInUserActivity. When user pressed onBackPressed in SignInUserActivity, the app should close (or move to background)>
2) After the user signs in, user should NOT be able to go back to the SignInUserActivity by onBackPressed enough times or navigateUp button on toolbar, onBackPressed should ONLY close the app (or move it to background). Currently, I have
#Override
public void onBackPressed() {
super.onBackPressed();
finish();
}
in my MainActivity, yet
3) If the user signs out from MainActivity, in SignInUserActivity, onBackPressed should not direct the user back to MainActivity (with empty data since the session was already deleted). Currently the way I'm handling it is redirecting the user back to SignInUserActivity:
public void handleRedirect(String sessionId) {
if (sessionId == null) {
Intent requireSignInIntent = new Intent(this, SignInUserActivity.class);
startActivity(requireSignInIntent);
}
}
but instead it should be overriding onBackPressed?
It seems your problem can easily be resolved by starting a new Activity Stack. Just add this when you start SignInActivityand when you navigate to other Activity after a succefull log in
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
This flags should cover your 1st and 2nd problem. As for the 3rd problem, it seems you're doing the logic well but I didn't quite get that last part.

Check whether an activity is active or not from a different activity

I have a flow in my application like this:
For new users:
Splash Screen --> Login Activity --> Home Activity
For already registered users:
Splash Screen --> Home Activity
Basically the Splash Screen has an if else to decide which activity to go to. Once a first time user logs in, his status is saved in a preference variable for the splash screen to decide next time not to open the login activity.
Now the situation is that. If a new user logs in and goes to the home activity, and then logs out. He is redirected to the Login screen which is pretty much what should happen. But, in case an existing user opens the app, he is shown the Splash screen and directly moved to the Home Activity. Now if the user logs out, he gets out of the app. This happens because the Login Activity does not have any instance created and thus finishing the Home Activity finishes the whole app. Logout actually finishes the Home Activity, naturally the last active activity should open up. Which is not happening.
What I want to do is that, I want to implement a logic which will check that the Login Activity is available or not. If its available then finish() will be called else the Login Activity will be called via intent.
Please tell me how to achieve this.
P.S: My app uses a custom theme with a customized action bar. If I call finish and Intent together or I use flags to clear existing activities then there is a weird transition effect which shows the black standard action bar for a split second thus creating a bad user experience.
Now if the user logs out, he gets out of the app. This happens because
the Login Activity does not have any instance created and thus
finishing the Home Activity finishes the whole app.
If i understood your question, why dont you just call the Login Activity manually after user click a logout button?
Its what i always did with apps that have flow like yours
when user login finish login activity and start home activity.
when user logout finish home activity and start login activity
You always can call Login Activity via intent. If the activity is available, android will show this activity. Else android will create new activity automatically.
Actually that's why we use intents to show activity instead of creating activityes manually. System catches this intents and does all dirty work.
EDIT:
Hmm, but wouldn't you have the transition problem anyways? (If you were already logged in, and then log out - using intent/finish() you will have the same black action bar issue no?)
Maybe consider following ( I actually did this in my app):
Merge Splash screen and Login into one activity and depending whether you are logged in - display the login fields or proceed to home screen. Then you have a out of box consistent stack of activities regardless of use cases and no mambo-jumbo with do I already have this or not.
I can't comment because of I lack 4 rep, so I'll post as answer here:
I think #Blaze Tama is right. You can also use FLAG_ACTIVITY_CLEAR_TOP on intent to avoid stack flow problems:
From docs:
If set, and the activity being launched is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it will be closed and this Intent will be delivered to the (now on top) old activity as a new Intent.
Always start Login activity and start Home activity right away if the user already logged in.
In the Splash Screen activity
Intent intent = new Intent(this, Login.class);
If (user already logged in)
{
intent.putextra("Logged in", true);
}
startActivity(intent);
In the Login activity
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Intent intent = getIntent();
if (intent != null)
{
if (intent.getBooleanExtra("Logged in", false))
{
startActivityForResult(new Intent(this, Home.class), requestCode);
}
}
else
{
// The existing code here
}
}
In Home activity send back a code to indicate if the user logged out or just BackPress. If BackPress finish this Login activity.

bringing up different page when logged in

let me start off by saying happy holidays to everyone!
ok i really just need confirmation and correction if needed.
what im trying to do:
Im using google and facebook "Log-in" feature to sign in for my app to retrieve the data needed like name email etc.
where i Need help:
after signing in i want another activity to be the forefront everytime app opens unless the user signs out then of course, it takes them back to the original main page to sign back in.
now im assuming this takes place in maybe the lifecycle right?
somthing like:
#override
OnResume
{
//if user is signed in cast an Intent to automatically go to another activity?
}
am i on the right track on no? thanks in advance guys
I'm not sure off the top of my head how Google and Facebook's login is implemented... do they have a sample project you're using?
And yep, you're on the right track! Generally speaking you should be able to have a "Main" activity (MainActivity for this example) which checks to see if the login was successful, and if so, kicks you to the activity you want (LoggedInActivity).
This would be in the onCreate() or onResume() method of MainActivity.java
onResume() { // onCreate() should work, too.
if (loggedIn) {
startActivity(new Intent(this, LoggedInActivity.class));
} else {
// send them to login
}
}
If there's not a good way to check if they're logged in, you could save a boolean value or api token using SharedPreferences once the login is successful, and check that value (that'd be the value of loggedIn) every time at launch. You'd obviously need to clear that value any time you logged out.

Categories