Firebase auth gets stuck on iOS login without error - javascript

I've set up the most basic implementation of firebase auth login with email and password.
firebase.auth().signInWithEmailAndPassword(email, password).then(() => {
console.log('Logged in')
window.location.href = "./home.html"
}).catch(function (error) {
console.log(error)
});
For some reason, on iOS, the login process sometimes gets stuck waiting for the promise of signInWithEmailAndPassword() to resolve. I don't get any error message.
The only way to re-enable the login mechanism is to clear the browser cache.
Is this a known problem? I've been experiencing this problem for my last two apps over the last year.
Edit: After further trial and error I found out that the problem usually happens after being logged in, letting the iPhone go to sleep, waking it back up, and then logging out. Then the same problem also happens for the signOut() function.

Turns out the problem had to do with the domain not being whitelisted in my project settings. The reason why I didn't pay attention to the console alert about oAuth was that it did work most of the times, even with it showing. So I thought it didn't have any effect on it.
The answer was suggested in this thread

I was having the same issue, but it was even more consistent when I moved to version 9 of the firebase sdk and my app was running in an Ionic-Capacitor native app on iOS. The solution was to add "localhost" to Firebase > Authentication > Sign-in method > Authorize domains (NOTE: if you use localhost make sure you have sufficient security db rules to prevent someone from adding bad data and you may not want to use this in production).
Then I needed to use intializeAuth() when running in hybrid (native app) mode. My app is also a pwa and getAuth(app) makes assumptions that its loading in a browser environment which causes this problem.
const firebaseApp = initializeApp(FirebaseConfig);
this.firebaseAuth = isPlatform('hybrid') ?
initializeAuth(firebaseApp, {persistence: indexedDBLocalPersistence}) :
this.firebaseAuth = getAuth(firebaseApp);

Related

Creating A 'User Only' Section In A Firebase Site

I'm hoping to be able to create a section of a site that is unable to be read/seen by anyone that's not logged in... I am using Firebase and Javascript
I have read that you are unable to set permissions for files (.htmls ect) so i wont be able to block people from seeing the pages as a whole... Ive also read that this isn't the best practice anyway... So my question is...
What is the protocol for doing this sort of thing? And how can this be done in Firebase?
I have managed to create a user only page before from a tutorial, but this was just done by hiding the content of the page with Javascript and also blocking the permissions to the displayed data through Firestore permissions.
But I don't feel this is adequate for my site as I don't want people being able to read the code in the background or get access to the page at all to begin with.
I have also read that a way to go about doing this is to use Firebase Cloud Functions to check weather the user is logged in and if they are then it spits out the code for the pages from the google servers. Is this a good idea? Or is there a better way?
Any help, tips or insights would be greatly appreciated.
Just trying to get a feel for where to begin with this problem.
Hoping there is a solution.
Thanks
Yes, its a good practice hiding or preventing the UI to be rendered for unauthorize users.
Yes, its also a good practice setting the permissions accessing your data from the database.
You should also consider middleware, navigation guards or route guards for preventing unauthorized users to visit the restricted page. It would depend on the stack, or what frontend technology you are using. You can find whatever navigation guard you chosse. For vuejs there is vue-router. Also you can use firebase authState listener. Depends on your choice.
Use firebase auth to signInWithEmailAndPassword, or whatever your authentication method was. Then, you can check the auth state in onAuthStateChange, and set your new userId state:
// somewhere...
const [currentUserId, setCurrentUserId] = useState(null)
// later..
onAuthStateChanged(auth, (user) => {
if (user && user.uid) {
setUserId(user.uid)
}
});
// even later in this component:
return (<Layout userId={currentUserId} />);
// in wherever you have links, I assumed you passed currentUserId to here:
return (
currentUserId != null ? (Give content pls) : routeToLogin();
);
Something like this should be fine and secure enough. Noone is gonna go and flip a variable in your extremely obfuscated, transpiled javascript code generated by your bundler, and even if they did find a place to flip a variable, the code would probably throw an error anyway.
You could lazy load that certain page as well once authenticated, then the code for it it wouldn't even be loaded into the users disk until they've successfully signed in.

How do I debug authentication in Firebase?

Currently, when I set authentication signinflow to redirect, the login process doesn't complete, although it does go to the Google or Facebook login screen. However, when I set the signinflow to popup, the authentication process works as intended. What I'm curious about is how do I go about debugging the authentication in Firebase? The console only shows front-end javascript related code obviously, and the DebugView in the firebase console doesn't show anything when I login or logout whether it's via popup or redirect. What are the steps involved in finding out where the authentication error is in relation to the redirect signinflow mode?
My app.js code is as follows:
firebaseUI.start('#firebaseui-auth-container', {
signInFlow: 'redirect',
signInSuccessUrl: 'http://www.bing.com',
signInOptions: [
firebaseDB.firebase_.auth.EmailAuthProvider.PROVIDER_ID,
firebaseDB.firebase_.auth.GoogleAuthProvider.PROVIDER_ID,
firebaseDB.firebase_.auth.FacebookAuthProvider.PROVIDER_ID
],
});
firebase.auth().onAuthStateChanged(user => {
if (user) {
console.log(user.displayName);
} else {
console.log('no user signed in');
}
});
Several tips come to mind:
(1) Look carefully at the JavaScript console logs on your browser. JavaScript is rather notorious for "spit out an error-message (in a place where you'd ordinarily never see it ...) and keep going."
(2) Look carefully at the server-side logs, both for Firebase and for the web server. The sequence of interest probably involves one or more "round trips" between several different pieces of software, and you need to methodically, systematically reconstruct exactly what took place and in what sequence. "The whole time-line."
(3) "Don't assume!" "Trust, but verify," as they say. Don't act on any "assumption" as to what the actual problem is – e.g. here you probably "assume" that it's a problem in "Firebase authentication." Assumptions can send you "chasing after white rabbits" for a distressingly long time, only to come up empty-handed. (Trust me on this one ...)
You probably won't get too much useful information from a "TCP/IP dumper" (such as tcpdump ...) because the communications is probably encrypted.

How can I Choose Specifc Users to Log Into my Javascript SPA in Azure AD?

I'm using a Javascript SPA to return a query from Microsoft Graph through the Azure AD application, and it works just fine!
The problem is when I try to loggout from the application, it says I was successfully logged out but if try to log in with another user, it logs into the previous one, in this case, me, without even asking for password.
I needed that this application could log in just few people in my organization, but anyone with "#example.com" can access my application, without the need to be signed to it or not.
I've already cleared the browser's cache and cookies and it doesn't work. Already configured the app to store the cache in the session but it also failed.
The code I'm using is available in:
https://learn.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-javascript-spa
The only differences are that I'm using another querys instead the "https://graph.microsoft.com/v1.0/me" and the permissions needed to get them.
I just needed a way to choose specific people to log into the application instead of all the organization and to fix this logout problem.
If I understood you well, I believe your solution is the option select_account.
Here is a code snippet to illustrate:
const clientApplication = new Msal.UserAgentApplication(config);
const loginRequest = {
scopes: [config.webApiScope],
prompt: "select_account",
}
clientApplication.loginPopup(loginRequest).then(function (loginResponse) {
//your code
});

Firebase 'A network error (such as timeout, interrupted connection or unreachable host) has occurred.'

I'm trying to write some tests for my database client which requires me to first authenticate into Firebase.
I'm using Jest as my test runner.
My test looks like:
it ('should sign in ', async (done) => {
try {
await auth.signInWithEmailAndPassword('testabc#test.com', 'testuser');
} catch (e) {
console.log(e);
}
done();
});
My firebase app has been initialized and I have validated that the API key is correct.
A couple of interesting notes are that even though I get:
'A network error (such as timeout, interrupted connection or unreachable host) has occurred.'
On the firebase console, I see that my test user has signed in. Mirroring: Firebase throws “auth/network-request-failed” on signInAnonymously() while running jest tests
It doesn't seem like an authentication issue (wrong password/wrong email) as I get the same error for attempting to login as a user that does not exist.
Sign in via launching my app through the browser and inputting credentials into input fields works with no issues.
Any ideas?
I've had similar results when there was Proxy and/or certificate issues blocking things.
What I would do is first enable logging: firebase.database.enableLogging(true);
Then take a look at what it says. If you can't see what is blocking I'd then run Wireshark, we were able to see what was happening then.
This problem occurs when there is no active internet connection in your mobile.
I received the same error because I forgot to enable my network connection in my device. First check your Android manifest file to make sure you have granted network permissions. In my case it was done. So I used my emulator then it started working fine. (For more thorough diagnasis you can use if clause to check whether internet connection is active or not)
1- Reason is Simple ! Check if Device has internet connection.
2- if you have google services enabled
In my case It happened using the Android Emulator.
Closing and restarting the Emulator solved the problem
In my case it worked when I changed
auth.useEmulator('http://localhost:9099')
to
auth.useEmulator('http://127.0.0.1:9099')
in my jest tests.
I had also the same problem, Just restart your IDE and emulator and make sure that have connected wifi. Then open again and run your app.

Google Auth API Javascript idpiframe initialization error on Chrome

I use GSuite and I'm coding a very simple web app to use Google Auth API, and I get an exception "idpiframe_initialization_failed".
Now I have the exact HTML as shown in the google Sample:
https://developers.google.com/api-client-library/javascript/samples/samples
1) I've created a project on the Google Developer Console
2) I setup the OAUTH authorization screen
3) I've created the client ID, creating restrictions and redirection URL
4) I've also created the API KEY
5) Finally I've enabled the People API, because discovery services was failing when setting the discoveryDocs parameter
With all of these steps, When I call the gapi.client.init, it raises an exception ONLY in chrome, I cannot understand why.
The code for initializing the API is:
gapi.client.init({
apiKey: 'MY_API_KEY',
discoveryDocs: ["https://people.googleapis.com/$discovery/rest?version=v1"],
clientId: 'MY_CLIENT_ID.apps.googleusercontent.com',
scope: 'profile'
}).then(function (response) {
// Listen for sign-in state changes.
gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
// Handle the initial sign-in state.
updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
},function(reason){
console.log('onerror');
console.log(reason);
// Listen for sign-in state changes.
gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
// Handle the initial sign-in state.
updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
The code is running the error block, and the message is:
details: "Failed to read the 'localStorage' property from 'Window': Access is denied for this document."
error:"idpiframe_initialization_failed"
Any ideas why I'm coming into this error?
Thanks!
I encountered the same issue. After investing some time, found the reason. This error is because in chrome settings, you have the Block third-party cookies and site data option enabled.
It can be resolved by disabling this option:
"To find the setting, open Chrome settings, type "Content settings" in the search box, click the Content Settings button, and view the fourth item under Cookies."
Uncheck the box "Block third-party cookies and site data".
Hopefully this helps you in resolving your issue.
The problem is with Google's API console and how it handles creating credentials.
It only seems to work when I access it through the following url
https://developers.google.com/identity/sign-in/web/sign-in#before_you_begin
There is a link that lets you create your app and the OAuth credentials.
When I go to the console and create it through that screen it doesn't seem to work.
After trying and re-create again and test with a fresh app I found out that the URL you add to the Authorized Javascript Origins doesn't always get added.
If everything is good then the url should be available in the credentials page
In my case, I just had to wait a bit for Google to take the origin into account. I cannot tell exactly how long it took. I waited ~30min. I then went to sleep and it was working the following morning.
Edit: Ooops I just realized I was using http:// and not https://. That was the actual problem.
I had the same problem and I searched for 3 days: Resolve " popup_closed_by_user" Go to your console.google go to your API MANAGE : Credentials:modify your credentials:
Authorized Javascript origin (http://localhost:port);
authorized redirect URI(http://localhost:port/auth/google/callback);
Example:|| Authorized Javascript origin (http://localhost:4200);
authorized redirect URI (http://localhost:4200/auth/google/callback)

Categories