In my Flutter Mobile App authentication is handled by my own server API
Currently I have an ask reset password feature in my mobile app which sends a reset password link to the user’s email inbox.
This link opens a web page inside the user’s browser, where they enter a new password.
Instead of opening a web page I’d like this link to open my mobile app at specific reset password route + persist & provide to that route the reset password code
What kind of attributes should my link have to achieve this behavior & provide the reset code to the route ?
Is there a way to achieve any of this without using Firebase Dynamic Links ?
What do I need to setup inside my Flutter App to achieve any of this logic ?
I’m using BLoC state management.
You have to use deep link and while creating the deep link if on mobile open the app and navigate to that page and if app is unavailable then take the user to the web page.. Deep linking is not connected to firebase auth.. Both are different services and deep link will work even without firebase auth.
EDIT
when creating deep link add the extra data in the link like the following
Future<Uri> createDynamicLink(String id) async {
final DynamicLinkParameters parameters = DynamicLinkParameters(
uriPrefix: 'https://your.page.link',
link: Uri.parse('https://{your URL}.com/?id=$id'),//<----id=some value is custom data that you wish to pass
androidParameters: AndroidParameters(
packageName: 'your_android_package_name',
minimumVersion: 1,
),
iosParameters: IosParameters(
bundleId: 'your_ios_bundle_identifier',
minimumVersion: '1',
appStoreId: 'your_app_store_id',
),
);
var dynamicUrl = await parameters.buildUrl();
return dynamicUrl;
}
To retrieve this
final PendingDynamicLinkData data = await FirebaseDynamicLinks.instance.getInitialLink();
Uri deepLink = data?.link;
if (deepLink != null) {
if (deepLink.queryParameters.containsKey('id')) {
String id = deepLink.queryParameters['id'];
Navigator.of(context).push(MaterialPageRoute(builder: (context) => SomeScreen(id: id);
}
}
you can check this for reference
https://blog.devgenius.io/firebase-flutter-dynamic-links-step-by-step-guide-630402ee729b
Related
I want to add ofl so when the link is opened on a desktop it will go to the web version of the app
Here's my code where should I add it?
final DynamicLinkParameters parameters = DynamicLinkParameters(
// The Dynamic Link URI domain. You can view created URIs on your Firebase console
uriPrefix: uriPrefix,
// The deep Link passed to your application which you can use to affect change
link: Uri.parse(parsableLink),
// Android application details needed for opening correct app on device/Play Store
androidParameters: AndroidParameters(
packageName: androidPackageName, fallbackUrl: Uri.parse(webLink)),
// iOS application details needed for opening correct app on device/App Store
iosParameters: IOSParameters(
bundleId: iosPackageName, fallbackUrl: Uri.parse(webLink)),
//longDynamicLink: Uri.parse('$parsableLink&ofl=$webLink')
);
final ShortDynamicLink shortDynamicLink =
await dynamicLinks.buildShortLink(parameters);
print(shortDynamicLink);
return shortDynamicLink.shortUrl.toString();
Okay so I figured that out I had to add the longDynamicLink like this :
"$uriPrefix/?link=$parsableLink&apn=$androidPackageName&afl=$webLink&ibi=$iosPackageName&isi=$iosId&ifl=$webLink&ofl=$webLink"
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 have the below code which does generate the dynamic link correctly. However, when I share the link using Share plugin I just see the link text. Nothing else appears in the shared message. None of the social tags attributes are shown when the link is shared.
Second thing, the link also does not open in the browser - it always tries to find the app on google play store. My app isn't on the play store yet and I want it to always point to browser. The dynamic link I configured on playsore does open in the browser but the links created via code go to the play store - always. The DL I configured also does NOT show any social media info.
final DynamicLinkParameters parameters = DynamicLinkParameters(
uriPrefix: 'https://zakaas.page.link',
link: Uri.parse("https://firebasestorage.googleapis.com/v0/b/removed_strage/o/UserVideos%2F2020-06-21%2017%3A42%3A54.530730.mp4?alt=media&token=removed_token_value"),
androidParameters: AndroidParameters(
packageName: 'com.clidio.zakaas',
minimumVersion: 21,
),
navigationInfoParameters: NavigationInfoParameters(
forcedRedirectEnabled: false,
),
dynamicLinkParametersOptions: DynamicLinkParametersOptions(
shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short,
),
socialMetaTagParameters: SocialMetaTagParameters(
title: 'Example of a Dynamic Link',
description: 'This link works whether app is installed or not!',
),
);
final Uri dynamicUrl = await parameters.buildUrl();
final ShortDynamicLink shortenedLink = await DynamicLinkParameters.shortenUrl(
dynamicUrl,
DynamicLinkParametersOptions(shortDynamicLinkPathLength: ShortDynamicLinkPathLength.unguessable),
);
Share.share('${shortenedLink.shortUrl}', subject: '${shortenedLink.shortUrl}');
OK. After a simple thought, I got this working now. I used a social app "HIKE" when I was testing and unfrtunately it did not work on hike. I don't use whatsapp for >2 years now but then I gave a try on friend's whatsapp and it did work . It shows image as well.
Thank you
I am trying to implement stripe connect in my flutter app. Here are the steps I need to implement. Can anyone please navigate me on how I could achieve this in Flutter?
I am able to create a button with the endpointUrl but that's all..
Thanks
I found out this myself using firebase cloud functions:
first you create an https function in the firebase cloud function
then you add the link created by the function to your stripe dashboard
then you write the following logic to your function
obtain the the authorisation code
fetch data from stripe
save the response somewhere (in my case in realtime database)
Here is the function
exports.connectStripeStandardAccount = functions.https.onRequest((req, res) => {
let authCode = req.query.code;
return stripe.oauth.token({
grant_type: 'authorization_code',
code: authCode,
}).then(async response => {
await admin.database()
.ref(`/accounts/${authCode}`)
.set(response);
return res.send("Well done, account integration is completed. You can now close the window and go back to the app");
});
});
The answer selected is not completely correct:
If you dont assign the account_id to a user then it's of no use.
The only way to pass the user_id (fUser.uid) is to pass it using the state parameter.
exports.StripePI = functions.https.onRequest(async (req, res) => {
// console.log('accountIdq ' + req.query.error);
// console.log('accountIdq ' + req.query.state);
// return;
// if(!req.query.code)
// return res.send("An Error has occured please try again");
const response = await stripe.oauth.token({
grant_type: 'authorization_code',
code: req.query.code,
}).then(async response => {
var connected_account_id = response.stripe_user_id;
await admin.firestore().collection('Registration').doc(req.query.state)
.update({customer_id : connected_account_id});
return res.send("Well done, account integration is completed. You can now close the window and go back to the app");
});
});
If you want to create an in-app stripe connect account registration with flutter you will need these:
A server or service to complete the OAuth like Firebase Functions or Integromat (I used Integromat)
A link that will redirect to your app (I used Firebase Dynamic Link)
STEPS TO CREATE THE REGISTRATION FLOW
INTEGROMAT/FIREBASE FUNCTIONS SETUP
I decided to use Integromat instead of Firebase Functions because is easier to set up, doesn't need any code, and decreases my server load.
If you want to create it on Firebase Functions you will need to have a Blaze Plan
If you don't know it, Integromat will automate processes that you currently handle manually, via webhooks. It is not only capable of connecting apps (like GoogleCloud, Facebook, AWS...) but can also transfer and transform data.
Create a new scenario and add a Custom Webhook. Click on it and click on add, name it, and save it. It will now create a custom link to your webhook.
Close and click on the semi-sphere next to the webhook, to add the new module.
Select HTTP and Make a Request.
In the URL section insert https://connect.stripe.com/oauth/token.
Method POST.
Body Type Application/x-www-form-urlencoded.
Create now those fields :
Key client_secret - value your stripe client secret You can find it on your stripe dashboard. I advise you to first use the test mode and after that, change the value to the live key.
Key grant_type - value authorization_code
Key code - leave the value blank. We will add it later.
Save and close
For Firebase Functions you can create a new HTTPS function (I didn't test this)
var stripe = require("stripe")(*your stripe client secret*);
exports.connectStripeStandardAccount = functions.https.onRequest((req, res) =>{
let authCode = req.query.code;
return stripe.oauth.token({
grant_type: 'authorization_code',
code: authCode,
});
});
Remember to install stripe package npm install stripe
STRIPE SETUP
If you are in the test mode go to this link
If you are in the live mode go to this link
Go on the bottom and activate oAuth for standard accounts or for Express Account.
Click on Add URI and add the webhook link of Integromat that you created or the link related to your Firebase function.
If you used Firebase add this link https://us-central1-<project-id>.cloudfunctions.net/connectStripeStandardAccount
For Integromat you will need to create the structure. To do this click on Test OAuth, copy the link, and open it in incognito mode. Open your Integromat scenario and click on your webhook. Now click on Re-determine data structure.
Return to your stripe registration page and click on Ignore account form at the top.
Return on Integromat and select the HTTPS request, modify the field code, and insert the variable code (will open a dialog with all queries from the webhook). Confirm and save.
Now click on the play button and reopen the stripe registration link in incognito mode and click on Ignore account form. Return in Integromat and add a JSON module after the HTTPS request. In the JSON string insert the Data variable and save. Create a Webhook Response module after the JSON module.
In the status put 301, then click on Ok.
DEEP LINK SETUP
It's time to set up the redirect link that will return the user to our flutter app or on our website if the user hasn't it installed.
I used Firebase Dynamic Link You can follow this tutorial for set up.
Go to the dashboard and create a new Link prefix and a new dynamic link, remember to select to redirect your users to the right app.
Click on the three dots in your dynamic link row and click on Link Details. Copy the extended link.
Open Integromat and select the last module you created (Webhook Response). Click on Show advanced settings and on the Header add :
Key Location - value the extended dynamic link that you copied.
If you want your app to elaborate data from the stripe OAuth response you can modify the extended dynamic link by adding ? on the link parameter: link=https://test.page.link?stripe_user_id={{14.stripe_user_id}}
And select the variable parsed from the JSON module. Remember to click on the save icon to save your scenario.
On Firebase Functions you can do this when the function stripe.oauth.token finish (I didn't test it):
res.setHeader('Location', your dynamic link);
res.status(301).send();
Remember to deploy it.
FLUTTER APP SETUP
The code here is very simple. To initialize the connect account registration you only need to set up a button that will launch the stripe connect URL. You can use launch(url);
You can find that URL here. Remember to be logged in to your stripe account to get the right stripe client id. You can easily get it in the same section you added the webhook link in your stripe connect settings.
Delete &redirect_uri=https://sub2.example.com on the URL.
Now you can test your app and will see that when you complete your stripe connect registration/login you will be redirected to your app.
If you want to have an in-app web view you can use this package
To handle the response, you need to have installed the package firebase_dynamic_links
Set your Main widget Stateful and on the initState run the method getDynamic() :
void getDynamic() {
FirebaseDynamicLinks.instance.getInitialLink().then((value) {
if (value != null) {
_connect(value);
}
});
FirebaseDynamicLinks.instance.onLink(onSuccess: (value) async {
if (value != null) {
_connect(value);
}
}, onError: (error) async {
debugPrint('DynamicLinks onError $error');
});
}
void _connect(value) {
Uri deepLink = value.link;
print("Link :" + deepLink.path);
print("Query :" + deepLink.queryParameters.toString());
String stripeUserId = deepLink.queryParameters["stripe_user_id"];
}
You need to have both of them to handle dynamic links when your app is running and when it's closed.
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';
}
}