Ionic - flashes with wrong starting page on app start - ionic-framework

Ive created 2 route guards... one which checks if the user is logged in and one if they are unauthenticated
When the app starts, very briefly it determines, while looking for the localstorage cookie, that the user doest exist and so shows the unauth page (i.e login page)
Im wondering what is the best approach to solve this - in my eyes the authguard with observale to see if the user is logged in or not was the best approach but there is that split second while the code runs that it cannot determine and it wants to show something.
Anyone have any similar issues/creative solutions to solve it.

I had this same issue a few months ago, and I solved it by creating an Auth Guard and returning a promise...
auth.guard.ts
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot,
): Observable<boolean> | Promise<boolean> | boolean {
return new Promise(resolve => {
const userAuthObs = this.afAuth.user.subscribe(user => {
if (user) {
resolve(true);
} else {
this.router.navigate(['signup']);
resolve(false);
}
});
});
}
The app just continues to load normally while it waits for this promise to decide where to direct the user.
You can watch a great video about creating auth guards here...
https://www.youtube.com/watch?v=RxLI9_ub6PM

Related

Detect if user is connected to firebase app

I want to implement an "isActive" feature on my app that is built using firebase firestore. I am using firebase functions along with authentication in my React App.
Is there a way of detecting if the user is "active" or "inActive" on my app by triggering a cloud function when they login or disconnect to the app?
If i can determine this i would store the value in firestore and handle it in the frontend to display a UI.
Thanks
I see two aspects to the question here:
Auth state: You want to track the logged-in duration of the user.
Focus state: You want to track when the user is active on the app.
For #1, you will have to listen to the auth state changes, and you may also want to change your auth state persistence strategy accordingly. From https://firebase.google.com/docs/auth/web/auth-state-persistence:
Enum
Value
Description
firebase.auth.Auth.Persistence.LOCAL
'local'
Indicates that the state will be persisted even when the browser window is closed or the activity is destroyed in React Native. An explicit sign out is needed to clear that state. Note that Firebase Auth web sessions are single host origin and will be persisted for a single domain only.
firebase.auth.Auth.Persistence.SESSION
'session'
Indicates that the state will only persist in the current session or tab, and will be cleared when the tab or window in which the user authenticated is closed. Applies only to web apps.
firebase.auth.Auth.Persistence.NONE
'none'
Indicates that the state will only be stored in memory and will be cleared when the window or activity is refreshed.
import { getAuth, setPersistence, signInWithRedirect, inMemoryPersistence, GoogleAuthProvider } from "firebase/auth";
const auth = getAuth();
setPersistence(auth, inMemoryPersistence)
.then(() => {
const provider = new GoogleAuthProvider();
// In memory persistence will be applied to the signed in Google user
// even though the persistence was set to 'none' and a page redirect
// occurred.
return signInWithRedirect(auth, provider);
})
.catch((error) => {
// Handle Errors here.
const errorCode = error.code;
const errorMessage = error.message;
});
You don't need a cloud function for th
For #2, you might want to check out this blog. https://javascript.plainenglish.io/validate-your-apps-session-on-focus-892f610f7e23.
import { useLocation } from '#reach/router';
import React, { useEffect } from 'react';
import { useDispatch } from 'react-redux';
export function WindowFocusHandler() {
const dispatch = useDispatch()
const location = useLocation()
useEffect(() => {
window.addEventListener("focus", onFocus)
return () => {
window.removeEventListener("focus", onFocus)
}
}, [])
const onFocus = () => dispatch(session.effects.checkSessionOnFocus(location))
return <></>
}
The Focus event on a window might get triggered more often if it is a browser app. Depending on what you want to achieve, both things should be possible in
your front-end code without the need for cloud functions. Although, you might opt to code the logic as a firebase function and invoke it from your react code when onFocus.

Ionic 4 intercept android back button for navigation

so in ionic 3 there was registerBackButton() but in ionic 4 this option is no longer there and has been sitting on the shelf for quite some time now.
I have read the post here that tries to solve the solution I am looking for, however, the back button still performs as it wants to.
this SO answer shows another way but it is the same idea of intercepting and navigating, however, I am just, for now, trying to dismiss the top modal in the stack.
scenario: users open a search modal(modal1) which then they click on a users profile modal(modal2). The person wants to go back to the search modal(modal1) but instead of clicking the nice button that allows them to do that, they use the hardware back button.
result: all modals(modal1 and modal2) are closed.
desired effect: using the hardware back button will allow for custom navigation based on logic in place.
attempted code:
this.platform.backButton.subscribeWithPriority(0, (): void => {
this.modalCtrl.getTop().then(
async (value: HTMLIonModalElement): Promise<void> => {
if (!!value) {
await this.modalCtrl.dismiss();
} else {
this.navCtrl.navigateRoot('/home');
}
},
);
});
also have tried :
// registering back, if there is a view on top, close it, don't go to home.
this.platform.backButton.subscribeWithPriority(0, async (): Promise<void>=> {
try {
console.log('try');
const element = await this.modalCtrl.getTop();
if (element) {
console.log('in true');
await element.dismiss();
}
} catch (error) {
console.log('error closing modal', error);
}
});
note when pressing the back button I never see ANY of the console logs... maybe things have changed a lot more? since the previous Stack overflow questions.
UPDATE:
If you are having this same issue then know you are not alone!
This, and many others are well known, see here for a list they are tracking the issues. Nothing else to do... but wait... I guess...
I will update this when there is a change

How can I keep the BarcodeScanner screen open without redirecting me to another page?

I am making an application that allows me to scan QR codes, and I managed to make the code work but my doubt is that when I scan the plugin phonegap-plugin-barcodescanner takes me out of the camera interface, what I want to do is to stay in it and show me an alert with the scanned code, and to give it ok in the alert to stay in it, to avoid being clicked to enter it.
I'm working with the plugin phonegap-plugin-barcodescanner, in ionic 3
public scanQR2() {
this._ButtonText = "Escanear";
this._barcodeScanner.scan().then((barcodeData) => {
if (barcodeData.cancelled) {
console.log("User cancelled the action!");
this._ButtonText = "Escanear";
return false;
}
console.log("Scanned successfully!");
console.log(barcodeData);
}, (err) => {
console.log(err);
});
}
I hope that the application when performing a scan stays on the same interface and does not redirect me to another page

Aurelia Push State App Reload on Login and Logout

When configuring Push State with Aurelia and Visual Studio, I am getting an odd behavior where after I select login my entire app reloads instead of the router just pushing to the homepage. This also happens when I logout, I get to the login screen and it refreshes the entire app. I am using Aurelia Auth. Any assistance would be much appreciated.
I think I had the exact same issue some time ago and this was one of the reasons I switched back to pushState = false (but my infos may be helpful for you).
Anyways, the following issue describes what I was facing: https://github.com/paulvanbladel/aurelia-auth/issues/55
The problem is, internally the plugin sets href:
Login - https://github.com/paulvanbladel/aurelia-auth/blob/master/src/authentication.js#L95-L99
if (this.config.loginRedirect && !redirect) {
window.location.href = this.getLoginRedirect();
} else if (redirect && isString(redirect)) {
window.location.href = window.encodeURI(redirect);
}
Logout - https://github.com/paulvanbladel/aurelia-auth/blob/master/src/authentication.js#L139-L143
if (this.config.logoutRedirect && !redirect) {
window.location.href = this.config.logoutRedirect;
} else if (isString(redirect)) {
window.location.href = redirect;
}
What you need to do is avoid both conditions, i.e. set loginRedirect and logoutRedirect to the empty string (''). Then, do the navigation on your own via Aurelias router as I did in my example from the GH issue:
return this.auth.login(userInfo)
.then(response => {
console.log('You signed in successfully.');
this.router.navigate('/contents');
})
Of course, do the same router navigation on your logout method.

Facebook action script 3 API login/logout issue

I'm making mobile AIR app for Android using Flash builder 4.5, AIR 2.6, Facebook action script 3 API the latest version.
I have a problem with login/logout. I can login only one time - then my data caches somehow and Facebook automatically logs me in. When I call logout I receive response TRUE, but I don't really logout from system. Standard login dialog doesn't appear for me. I have already read a lot of articles on stackoverflow and open issues on official site, but none of them were helpfull. How can I solve this? Here is the code I use:
package
{
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.display.Stage;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.external.ExternalInterface;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.system.Capabilities;
import flash.system.Security;
import flash.display.Loader;
import com.facebook.graph.FacebookMobile;
public class TestProj extends Sprite
{
public function TestProj()
{
super();
//register to add to stage
this.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
// support autoOrients
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
}
private function onAddedToStage(event:Event):void
{
this.removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
FacebookMobile.init("195053007196177", initCallback);
}
private function initCallback(success:Object, fail:Object):void
{
var appPermissions:Array = new Array("read_stream", "offline_access", "publish_stream", "read_friendlists");
FacebookMobile.login(loginCallback, this.stage, appPermissions);
//FacebookMobile.logout(logoutCallback);
}
private function loginCallback(success:Object, fail:Object):void
{
//And here I always receive success with my UserID
//and login dialog don't appears to me before this
if (success)
{
trace("login ok");
}
else
trace("login failed");
}
private function logoutCallback(success:Object):void
{
//here I reseive "TRUE" always!!
trace(success);
}
}
}
You're only passing the 1st argument of logoutCallback to your logout method. If you add in the 2nd argument of your site url specified for your app, it should clear it out the html cookie for that window. Also, set FacebookMobile.manageSession = false;
FacebookMobile.logout(logoutCallback, "http://your_app_origin_url");
There is a potential, related bug that involves Desktop and Mobile not accessing or clearing the access token's the same way. For that, there's a hack that describes exposing the access token in FacebookMobile, then manually calling the "logout" method with the access token. The issue is described here, including a method called "reallyLogout". If what I've written above doesn't work, implement "reallyLogout".
When you log out, your app clears the local session but does not log you out of the system. This is clearly defined in the documentation for logout. Think about it, if you're logged into Facebook on your Smartphone, Web Browser, and now this Mobile Desktop App, and suddenly you log out... it shouldn't log you out EVERYWHERE, just within that browsers session. So pass that 2nd parameter.
I've had this exact problem, and after trying numerous fixes, this finally seems to work:
The default logout functionality seems to not be properly clearing cookies via the FacebookMobile actionscript API. The solution in comment #33 here worked for me, reproduced here. Make sure to sub in your own APP_ID:
function logout(e:MouseEvent):void {
FacebookMobile.logout(onLogout, "https://m.facebook.com/dialog/permissions.request?app_id=APP_ID&display=touch&next=http%3A%2F%2Fwww.facebook.com%2Fconnect%2Flogin_success.html&type=user_agent&perms=publish_stream&fbconnect=1");
}
function onLogout(result:Object):void
{
trace("Perfect Log Out!")
}
Have had this Android Facebook clean logout problem the whole day, manage to solve it. Hope it helps. Here is my FB mobile handlelogin code to ensure all fb cookies and sessions are being removed and user will need to relogin.
Sometimes FB server is very slow. Its best to put a timer before you call handleLoginClick() again
function handleLoginClick():void
{
trace("connecting to facebook");
if (FacebookMobile.getSession() == null)
{
FacebookMobile.init(APP_ID, onHandleInit, null);
FacebookMobile.manageSession = false
}
else
{
var webView:StageWebView = new StageWebView();
webView.viewPort = new Rectangle(0, 0, 1, 1);
webView.stage = this.stage;
webView.loadURL("https://m.facebook.com/logout.php?confirm=1&next=http://www.facebook.com&access_token=" + FacebookMobile.getSession().accessToken);
webView.addEventListener(Event.COMPLETE,webviewhandleLoad);
function webviewhandleLoad(e:Event)
{
FacebookMobile.logout(null, "http://apps.facebook.com/<appName>/");
FacebookMobile.logout(null, "http://www.facebook.com");
webView.dispose()
webView = null
setTimeout(handleLoginClick,3000)
}
}
}
look at the solution of this problem. Maby someone it helps:
var stage_ref:Stage = PlatformUtil.originalStage(); //my custom class to get stage
var webView:StageWebView = new StageWebView();
webView.viewPort = new Rectangle(0, 0, stage_ref.width, stage_ref.height);
FacebookMobile.login(loginCallback, stage_ref, appPermissions, webView);
http://code.google.com/p/facebook-actionscript-api/issues/detail?id=381
http://code.google.com/p/facebook-actionscript-api/issues/detail?id=382
http://code.google.com/p/facebook-actionscript-api/issues/detail?id=383