I have developed a Flutter Web app that uses Firebase Authentication in order to sign in users to the app.
I've declared the Firebase Authentication persistence field so that the app will remember and auto-login the user when he revisits the Flutter Web app's URL, and won't be required to re-login every time he launches the URL.
It all works fine on a regular browser, but when the user generates a PWA (for example, clicking "Add to Home Screen" on iOS devices to save the website as PWA), the persistence feature stops working, and the user is required to re-login every time he opens the PWA.
Is there a way to add Firebase Authentication's persistence feature to a PWA? And if not, is there a way to prevent generating a PWA (and saving the Flutter Web app as a regular browser URL when clicking "Add to Home Screen" button on iOS, for example)?
Thank you!
To solve the persistence problem, add a listener:
FirebaseAuth.instance.idTokenChanges().listen((User? user) async {
if (user == null) {
// Function for user not logged in here. Do not write function to change page here.
} else {
// As it's a Future it will take a while to process the user's information, so it
will call the function after it's done.
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (_) => Home()));
}
}
This is an example I made and it worked, use controllers to change the status, put some function to wait for the information to be processed.
Hope this helps. Any questions, at your disposal.
Related
I just released my first app and It has a button in it that takes you to a website.
A user just sent me this:.
I tried googling Google's secure browsers policy but not much info is coming up.
how can I make my app comply with this policy? I think the button opens a browser in app (I use duckduckgo as my default browser and haven't had an issue)
is it just a case of opening a browser and then heading to the website when the button is pressed?
my code to open the website is:
_launchURL() async {
const url = 'https://www.thiswebsite.com';
final uri = Uri.parse(url);
if (await canLaunchUrl(uri)) {
await launchUrl(uri);
} else {
throw 'Could not launch $url';
}
}
thanks so much and any help would be greatly appreciated
Google is trying to make sure, you open this window in an actual new browser window, not in a webview still under the control of your application.
Your code should open an external browser.
Maybe the user has no browser installed on their device? Maybe their default browser is some exotic thing not recognized by Google?
If you are using the latest version of url_launcher (currently 6.1.8) there is not a lot more you can do.
You could force the app to take the external browser, not the in-app webview:
await launchUrl(_url,mode: LaunchMode.externalApplication);
But that should be what happens anyway. If your version is up to date, ask your user, what browser they use. Be prepared to tell them that they need to use another one.
I have created a flutter app which adds calendar events to user's google calendar using the google Calendar API. The app is doing the job but I have the following problem.
The app has initializeCalendarApi(); function(code attached below) in the initState() function which authenticates the user using Google Oauth. This is done by redirecting the user to user's browser where they select their Google account and click Allow to allow app to access their calendar. The problem is, once the authentication is done, the browser window is not closed automatically and the user has to close the browser app and shift to the flutter app manually which is bad for a production app.
How do I resolve this to make sure the user automatically gets back to the flutter app after clicking Allow.
Future<void> initializeCalendarApi() async {
var _clientID = new ClientId(Secret.getId(), "");
const _scopes = const [calendar.CalendarApi.calendarScope];
await clientViaUserConsent(_clientID, _scopes, prompt)
.then((AuthClient client) async {
CalendarClient.calendar = calendar.CalendarApi(client);
});
}
Image shows the final Page Obtained in browser after Oauth has been completed. I want to return my flutter app after successful authentication rather than this window opened in browser.
I'm adding integration testing (using the integration_test package) to my app but I am running into a problem.
Let me explain. The first step when my app launch is authentication for which I have 3 options: firebase email link, firebase google sign in, and firebase facebook sign in.
What is blocking me is that all these sign in methods require actions outside of the main app dart code and thus are not accessible by flutter driver.
Am I missing something here? And if not how should that case be handled?
Cheers!
To make the test less flaky i would recommend to not rely on an internet connection or a third party (like Firebase or Google login).
I would advise to use a Mock for this. So when you try to login to your test you send a fake response, and in that way you can continue using the app.
The following article explains how to use a mock:
https://medium.com/stuart-engineering/mocking-integration-tests-with-flutter-af3b6ba846c7
You can use Patrol – it lets you interact with native system UI from within your Flutter integration tests. Example:
import 'package:flutter_test/flutter_test.dart';
import 'package:patrol/patrol.dart';
void main() {
patrolTest(
'signs in',
nativeAutomation: true,
(PatrolTester $) async {
await $.native.enterText(
Selector(textContains: 'Email'),
text: 'tester#awesomeapp.pl'),
);
await $.native.enterText(
Selector(textContains: 'Password'),
text: 'ny4ncat'),
);
await $.native.tap(Selector(text: 'Continue'));
// you should be signed in
});
}
You can add the fourth way of signing in - using username and password. Firebase should support this kind of very common situation, so you can do it within lines of code.
If you do not want the end users to login by password, you can simply disable this method in production build and only enable it in debug build.
Another way is to mock your authentication system. In other words, when doing testing, you have a button called "fake sign in", and your integration test driver just click that button.
My flutter app requires payments to be made via PayPal in a web browser outside the app. Once the payment is completed the user will be returned to the app and a thank you page should be pushed.
I'm using _launchURL to initiate the web browser from within the app and the following example PayPal url to define the payment.
https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=email#domain.com¤cy_code=USD&amount=123.99&return=http://example.com&item_name=Document+Studio
Using SystemChannels.lifecycle.setMessageHandler I should be able to test when the app returns from the web browser (AppLifecycleState.resumed). But how do I capture the return URL (http://example.com) or some other value from the web browser to confirm that it has come from the transaction complete page and should be pushed to the apps thank-you page?
Is there a way to pass a value from the browser back to the app?
My other thought was to use Uni_links to "Deep Link" the thank you page within the app and have that as the return url parameter in the PayPal url?
I'm a bit lost with the solution and am only new to flutter, so any advice/guidance would be appreciated.
I am assuming you are using this _launchURL. To do what you desire create a ThankYou class and call it in the following manner. You might want to check resultingValue prior to calling your ThankYou screen. I haven't used the url functionality enough to know what it returns, if anything. It might be null, an int of some sort, such as 404 url not found, perhaps a String?
import 'ThankYou.dart';
_launchURL() async {
const url = 'https://flutter.io';
if (await canLaunch(url)) {
await launch(url).then((resultingValue){
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ThankYou()));
});
} else {
throw 'Could not launch $url';
}
}
i'am trying to made cordova application that need user login to (google + or Facebook)
so i show button for sign in to (google+ or Facebook)
but after i close the app and open it again i need the sign in button hide depending on last signed in account
i need to know how i can check if user signed after closing my application?
ie check if user subscribe with data login to my app or no?
You can check this when your application gets loaded in
function onDeviceReady() {
// Now safe to use device APIs
//Create small function which check for is access toke valid or not
//which returns Boolean true or false
// Else you can use localStorage.isSignInned and once logged in set it as true.
if(isSignInned)
{
//hide buttons
}
}
You can check facebook javascript api here and google javascript api here
It depends upon how you want your application to work.
I am attaching working sample which i created for Facebook for GooglePlus
hope this helps.!