Open Facebook app with url_launcher package in Flutter - flutter

I am trying to open the Facebook app on a company page in Flutter but it keeps opening it in the web browser instead.
It's just a simple widget that outputs a row of social media icons from a list:
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
class SocialMediaLinks extends StatelessWidget {
SocialMediaLinks({Key? key}) : super(key: key);
final List<Map<dynamic, dynamic>> icons = [
{
'name': 'twitter',
'launchUrl': 'twitter://PAGENAME',
'backupUrl': 'https://twitter.com/PAGENAME',
},
{
'name': 'facebook',
'launchUrl': 'fb://page/PAGEID',
'backupUrl': 'https://www.facebook.com/PAGENAME',
},
{
'name': 'instagram',
'launchUrl': 'instagram://PAGENAME',
'backupUrl': 'https://www.instagram.com/PAGENAME',
}
];
#override
Widget build(BuildContext context) {
return Row(
children: [
for (Map i in icons)
IconButton(
onPressed: () async {
await canLaunch(i['launchUrl'])
? launch(
i['launchUrl'],
forceSafariVC: false,
forceWebView: false,
)
: launch(
i['backupUrl'],
forceSafariVC: false,
forceWebView: false,
);
},
splashRadius: 30.0,
iconSize: 38.0,
icon: Image.asset(
"assets/images/icons/${i['name']}.png",
color: Colors.white,
),
),
],
);
}
}
Twitter and Instagram work and open in their apps but Facebook still only opens in the web browser. I've tried tonnes of solutions on stackoverflow but to no avail. Am I missing something?
Thanks.

I've observed a limitation with the supported URLs configured in the Facebook app. In Android at least, while the Facebook app has support for facebook.com, I noticed that the Facebook app opens when it's a link to a specific post i.e. https://www.facebook.com/$profileId/posts/$postId
However, the Facebook app seems to be unable to handle direct links to the profile or page i.e. https://www.facebook.com/$profileId
If you're linking to a profile/page in Facebook, you can pin a post in the profile/page and share the link of the Facebook post as a workaround. This should successfully open the Facebook app installed on the device.

Related

How to open link inside the pdf in webview flutter

I have added a pdfviewer in my Apps using Library flutter: flutter_cached_pdfview
some part of the code:
import 'package:flutter_cached_pdfview/flutter_cached_pdfview.dart';
goToReading(String link){
Navigator.push(context, MaterialPageRoute(
builder: (_)=> PDF(
enableSwipe: true,
swipeHorizontal: false,
autoSpacing: false,
pageFling: false,
onError: (error) {
print(error.toString());
},
onPageError: (page, error) {
print('$page: ${error.toString()}');
},
).fromUrl(link,
placeholder: (progress) => Scaffold(
backgroundColor: Colors.white,
body: Center(
child: Lottie.asset(
'assets/images/data.json',
height: 200,
controller: _controller,
onLoaded: (composition) {
_controller..duration = composition.duration..forward();
},
),
),
)
)
));
}
What I want is to open every link inside the pdf to open in webview for now it open in external browser (Chrome, safari),
************************************************************************I want it to open in internal webview inside the app it may be possible by using urllauncher but i dont know how to use it,
See this to understand my problem
See this to understand the current status
You have to set onLinkHandle and preventLinkNavigation:true in your file.
On onLinkHandle, you can set it to open WebView inside your app instead of opening the browser for it. Becuase by default it will always open web browser if you don't specify those things.

Flutter "Rate my App" always requires a Review when using native dialog on Android

I'm using the 'Rate my App' package to ask for rates in my app. https://pub.dev/packages/rate_my_app
I'm using the same code shown in the package page, but i'm setting the 'ignoreNativeDialog' parameter to false in order to use the native API even in Android. But when the dialog appears on android always requires a review after a rate.
Is it any way to set the review to be optional?
RateMyApp rateMyApp = RateMyApp(
preferencesPrefix: 'rateMyApp_',
minDays: 7,
minLaunches: 10,
remindDays: 7,
remindLaunches: 10,
);
rateMyApp.init().then((_) {
if (rateMyApp.shouldOpenDialog) {
rateMyApp.showStarRateDialog(
context,
title: 'Rate this app',
message: 'You like this app ? Then take a little bit of your time to leave a rating :',
actionsBuilder: (context, stars) {
return [
FlatButton(
child: Text('OK'),
onPressed: () async {
print('Thanks for the ' + (stars == null ? '0' : stars.round().toString()) + ' star(s) !');
await rateMyApp.callEvent(RateMyAppEventType.rateButtonPressed);
Navigator.pop<RateMyAppDialogButton>(context, RateMyAppDialogButton.rate);
},
),
];
},
ignoreNativeDialog: false, // This is the one parameter i set to false
dialogStyle: DialogStyle(
titleAlign: TextAlign.center,
messageAlign: TextAlign.center,
messagePadding: EdgeInsets.only(bottom: 20),
),
starRatingOptions: StarRatingOptions(),
onDismissed: () => rateMyApp.callEvent(RateMyAppEventType.laterButtonPressed),
);
}
});
Now it's clear.
The review was required becouse I was using it on a registered tester account. I tested with another account and it worked fine.

Problem in google login in canva through webview in flutter

I wanted to upload pics through canva from my flutter app that is why I am using the flutter-webview-plugin for the first time and therefore I am not able to solve this issue.
Code for the same is:-
import 'package:flutter/material.dart';
import 'package:kf_drawer/kf_drawer.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'dart:async';
class SettingsPage extends KFDrawerContent {
#override
_SettingsPageState createState() => _SettingsPageState();
}
class _SettingsPageState extends State<SettingsPage> {
final Completer<WebViewController> _controller =
Completer<WebViewController>();
#override
Widget build(BuildContext context) {
return SafeArea(
child: Center(
child: Column(
children: <Widget>[
Row(
children: <Widget>[
....
],
),
Expanded(
child: Container(
height: 500,
child: WebView(
initialUrl: "https://shree-hari.github.io/laxmi_canva/index.html",
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController){
_controller.complete(webViewController);
},
),
),
)
],
),
),
);
}
}
Please Help me to address this issue 🙄.
Google not allow native Flutter Web-Views to initiate OAuth.
For more info read Google Blog
In your case, I can suggest 3 Possible Solutions.
Try to Sign in with Email/Password instead of Google Sign In.
Use url_launcher to redirect the user to the browser.
If you don't want the user to leave your app
then you can use flutter_custom_tabs
this plugin use Chrome Custom Tabs to create a native experience inside the Flutter App.
You can add this userAgent :
WebView(
initialUrl: url,
userAgent: Platform.isIOS ? 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_1_2 like Mac OS X) AppleWebKit/605.1.15' +
' (KHTML, like Gecko) Version/13.0.1 Mobile/15E148 Safari/604.1' :
'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) ' +
'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Mobile Safari/537.36',
...
Use this package, it works like a charm
https://github.com/LinusU/flutter_web_auth
In the background, this plugin uses ASWebAuthenticationSession on iOS 12+ and macOS 10.15+, SFAuthenticationSession on iOS 11, Chrome Custom Tabs on Android and opens a new window on Web.
Your auth flow must land in the scheme you provide in callbackUrlScheme property. Then just parse the callback url and implement you own business logic around signin/signup
import 'package:flutter_web_auth/flutter_web_auth.dart';
// Present the dialog to the user
final result = await FlutterWebAuth.authenticate(url: "https://my-custom-app.com/connect", callbackUrlScheme: "my-custom-app");
// Extract token from resulting url
final token = Uri.parse(result).queryParameters['token']
https://stackoverflow.com/a/71297966/18723243
Using webview_flutter package you can fix the problem by adding userAgent: 'random', in the web view constructor. So, it will look like this:
WebView(
userAgent: 'random',
)

Cache in GrapghQl Flutter package settings and how to check it works

I'm trying to implement graphQl Flutter package in my app.
https://github.com/zino-app/graphql-flutter
Everything works well, but I have some issues with cache.
If we ran example from this package https://github.com/zino-app/graphql-flutter/tree/master/packages/graphql_flutter/example we can see that cache doesn't work.
In my app I also can't increase speed, it always get data online.
The code from this example
class GraphQLWidgetScreen extends StatelessWidget {
const GraphQLWidgetScreen() : super();
#override
Widget build(BuildContext context) {
final HttpLink httpLink = HttpLink(
uri: 'https://api.github.com/graphql',
);
final AuthLink authLink = AuthLink(
// ignore: undefined_identifier
getToken: () async => 'Bearer $YOUR_TOKEN',
);
Link link = authLink.concat(httpLink);
if (ENABLE_WEBSOCKETS) {
final WebSocketLink websocketLink = WebSocketLink(
url: 'ws://localhost:8080/ws/graphql',
config: SocketClientConfig(
autoReconnect: true, inactivityTimeout: Duration(seconds: 15)),
);
link = link.concat(websocketLink);
}
final ValueNotifier<GraphQLClient> client = ValueNotifier<GraphQLClient>(
GraphQLClient(
cache: OptimisticCache(
dataIdFromObject: typenameDataIdFromObject,
),
link: link,
),
);
return GraphQLProvider(
client: client,
child: const CacheProvider(
child: MyHomePage(title: 'GraphQL Widget'),
),
);
}
}
Animation that shows that cache doesn't work
So, the question is - what is the right way to implement cache and how check it works.
Thank you!
The examples are meant to be standalone - as such they use separate clients and caches. The consequence of this is that it is re-instantiated every mount. In other words, every time you navigates to the example's route, you get a new cache, so you can't see the caching effects. For a more substantial example where you can see if the cache is working, see the starwars example (related github discussion)

How do I open a web browser (URL) from my Flutter code?

I am building a Flutter app, and I'd like to open a URL into a web browser or browser window (in response to a button tap). How can I do this?
TL;DR
This is now implemented as Plugin
const url = "https://flutter.io";
if (await canLaunchUrl(url))
await launchUrl(url);
else
// can't launch url, there is some error
throw "Could not launch $url";
Full example:
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
void main() {
runApp(new Scaffold(
body: new Center(
child: new RaisedButton(
onPressed: _launchURL,
child: new Text('Show Flutter homepage'),
),
),
));
}
_launchURL() async {
const url = 'https://flutter.io';
final uri = Uri.parse(url);
if (await canLaunchUrl(uri)) {
await launchUrl(uri);
} else {
throw 'Could not launch $url';
}
}
In pubspec.yaml
dependencies:
url_launcher: ^6.1.7
Check out the latest url_launcher package.
Special Characters:
If the url value contains spaces or other values that are now allowed in URLs, use
Uri.encodeFull(urlString) or Uri.encodeComponent(urlString) and pass the resulting value instead.
If you target sdk 30 or above canLaunch will return false by default due to package visibility changes: https://developer.android.com/training/basics/intents/package-visibility
in the androidManifest.xml you'll need to add the following directly under <manifest>:
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
</intent>
</queries>
Then the following should word - for flutter 3 upwards:
const uri = Uri.parse("https://flutter.io");
if (await canLaunchUrl(uri)){
await launchUrl(uri);
} else {
// can't launch url
}
or for older versions of flutter use this instead:
const url = "https://flutter.io";
if (await canLaunch(url)){
await launch(url);
} else {
// can't launch url
}
launchUrl has a mode parameter which can be used to control where the url gets launched.
So, passing in launchUrl(uri, mode: LaunchMode.platformDefault) leaves the decision of how to launch the URL to the platform
implementation. But you can also specify
LaunchMode.inAppWebView which will use an in-app web view
LaunchMode.externalApplication for it to be handled by an external application
Or LaunchMode.externalNonBrowserApplication to be handled by a non-browser application.
For Flutter:
As described above by Günter Zöchbauer
For Flutter Web:
import 'dart:html' as html;
Then use:
html.window.open(url, name);
Make sure that you run flutter clean if the import doesn't resolve.
For those who wants to implement LAUNCH BROWSER AND EXIT APP by using url_launcher. Remember to use (forceSafariVC: false) to open the url in default browser of the phone. Otherwise, the launched browser exit along with your APP.
await launch(URL, forceSafariVC: false);
The best way is to use url_launcher package .
Add url_launcher as a dependency in your pubspec.yaml file.
dependencies:
url_launcher:
An example of how to use it :
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
void main() {
runApp(
MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Flutter is beautiful'),),
body: Center(
child: RaisedButton(
onPressed: _launchURL,
child: Text('Show Flutter homepage'),
),
),
)),
);
}
_launchURL() async {
const url = 'https://flutter.dev';
if (await canLaunchUrl(Uri.parse(url))) {
await launchUrl(Uri.parse(url));
} else {
throw 'Could not launch $url';
}
}
Output :
The launch method takes a string argument containing a URL .
By default, Android opens up a browser when handling URLs. You can
pass forceWebView: true parameter to tell the plugin to open a WebView
instead. If you do this for a URL of a page containing JavaScript,
make sure to pass in enableJavaScript: true, or else the launch method
will not work properly. On iOS, the default behavior is to open all
web URLs within the app. Everything else is redirected to the app
handler.
This is now implemented as Plugin
const url = "https://flutter.io";
final Uri _url = Uri.parse(url);
await launchUrl(_url,mode: LaunchMode.externalApplication);
pubspec.yaml
Add dependencies
dependencies: url_launcher: ^6.0.12
Output
If you want to use url_launcher than please use it in this form
environment:
sdk: ">=2.1.0 <3.0.0"
dependencies:
url_launcher: ^5.0.2
flutter:
sdk: flutter
This answer is also for absolute beginners: They are thinking behind the flutter sdk.
No that was a failure. The packages were extras and not in the flutter Sdk. These were secondary packages (single small framework helpers).
The PLUGIN plugin works great, as you explain in your examples.
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
final Uri _url = Uri.parse('https://flutter.dev');
void main() => runApp(
const MaterialApp(
home: Material(
child: Center(
child: ElevatedButton(
onPressed: launchUrlStart(url: "https://flutter.dev"),
child: Text('Show Flutter homepage'),
),
),
),
),
);
Future<void> launchUrlStart({required String url}) async {
if (!await launchUrl(Uri.parse(url))) {
throw 'Could not launch $url';
}
}
But when trying to open PDF https://www.orimi.com/pdf-test.pdf it remained blank, the problem was that the browser handled it in its own way. Therefore the solution was to tell it to open with an external application and it worked as expected.
Future<void> launchUrlStart({required String url}) async {
if (!await launchUrl(Uri.parse(url),mode: LaunchMode.externalApplication)) {
throw 'Could not launch $url';
}
}
In pubspec.yaml
#https://pub.dev/packages/url_launcher
url_launcher: ^6.1.5
using the url_launcher package to do the following:
dependencies:
url_launcher: ^latest_version
if (await canLaunchUrl(Uri.parse(url))) {
await launchUrl(Uri.parse(url));
}
Note: Ensure you are trying to open a URI, not a String.