I am trying to implement an OAuth2 implicit grant frow with a redirect.
Using the browser like this:
import { Plugins } from '#capacitor/core';
const { Browser } = Plugins;
await Browser.open({ url: loginUrl });
results in navigating to the login page, but then immediately jumping back to the previous (main app) screen. Any idea why? BTW, Angular's Platform.paused observable is getting triggered when opening the url and when jumping back (not-paused) as well
In case someone else stumbles upon this issue:
the problem was only on an Android Emulator, not on a real device. Wiping data in the AVD manager made it work in the Emulator as well.
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 try to add a Googla Pay button on a website. I follow the Google Pay implementation tutorial (https://developers.google.com/pay/api/web/guides/tutorial).
There is a code:
var paymentsClient = getGooglePaymentsClient();
paymentsClient.isReadyToPay(getGoogleIsReadyToPayRequest())
.then(function(response) {
//...
})
.catch(function(err) {
//...
});
I need to get some data from my server side before I call the above code so I do the http post request. Within success hanlder of my post request I call the above code. It works fine in my Android browser and my laptop browser. But it doesn't work from Safari. I get the "Unexpected developer error please try again later" error. If I call it without ajax request it works in Safari as well. Could someone suggest the solution?
Thanks for including the jsfiddle.
The reason that it's not working is because Google Pay tries to open a popup window when you call loadPaymentData in Safari. When a new window is triggered as the result of a click event (user initiated action), the popup window opens as expected. When it is triggered by a non-user initiated action, Google Pay gets loaded in the same window which ends up causing it to fail.
It looks like when you make an ajax request in the click handler and then call loadPaymentData, Safari considers it a non-user initiated action.
Check out the following example in Safari:
const ajaxButton = document.getElementById('ajax');
const nojaxButton = document.getElementById('nojax');
ajaxButton.addEventListener('click', event => {
$.get('/echo/json/', () => {
window.open('about:blank');
});
});
nojaxButton.addEventListener('click', event => {
window.open('about:blank');
});
I would recommend avoiding making any http calls on the button click event before loadPaymentData. If you can fetch the data before the button is clicked, then do so.
Out of interest, what kind of data are you fetching?
I have just started an Ionic 2 mobile app.
I am setting up an update password process where a user can enter their email, click a "send password update email" button which then emails them a link. They can click that link which takes them to a page where they can update their password.
How do I send them a link in their email that when clicked on will open up the app and take them to a specific page?
Even more complicated is that I have a web app also. So if I'm sending them an email, should I show update password on website and update password on mobile app links? Or should I just add a link to the website?
In order to open the mobile app from a link, you need to integrate a cordova plugin called cordova-plugin-customurlscheme. With this plugin you can register a custom url "protocol" that is unique to your app (eg. myAwesomeApp://register?token=123). After installing the plugin with your custom url, clicking on any link starting with myAwesomeApp:// will open your app and also trigger a function hooked on the window object called handleOpenUrl which accepts the url as param. Inside there you can do your routing, depending on the url param.
let self = this;
(<any>window).handleOpenURL = function handleOpenURL(url) {
setTimeout(() => {
if (url && url.indexOf('\register') !== -1) {
let token = URLHelper.getParameterByName(url, 'token');
self.setAsRoot(ConfirmEmailPage, { activationToken: token });
}
}, 0);
};
As for dealing with your web app, what you could do is the following (this is what I am currently doing):
Host online a page (say www.myAwesomeWebsite.com/register?token=123) that checks to see if the user is coming from a mobile device (iOS or Android more specifically). If so on page load redirect them to your myAwesomeApp://register?token=123 link and have a button saying install app from app store with a link to your mobile app. If the user has the app, the app will be opened by the redirect, if they don't they will get an alert saying link cannot be found or sth and after clicking ok they will see the install App from app store button. If the user is not coming from a mobile device, just redirect them to your web app myAwesomeWebApp.com/register?token=123.
Another option is to use a third party service for deep linking like branch
Hope that helps.
EDIT: Since I posted this answer Ionic team has come with their own plugin for deep linking that kind of simplifies some of the hooking up inside your app. Their detailed blog post can be found here. In essence you install their plugin:
cordova plugin add ionic-plugin-deeplinks --variable URL_SCHEME=ionichats --variable DEEPLINK_SCHEME=https --variable DEEPLINK_HOST=ionic-hats.com
and then hook to it like so:
import {Component, ViewChild} from '#angular/core';
import {Platform, Nav, ionicBootstrap} from 'ionic-angular';
import {Deeplinks} from 'ionic-native';
import {AboutPage} from './pages/about/about';
import {HatDetailPage} from './pages/hat/hat';
#Component({
template: '<ion-nav [root]="rootPage"></ion-nav>',
})
class MyApp {
#ViewChild(Nav) nav:Nav;
constructor(private _platform: Platform) {}
ngAfterViewInit() {
this._platform.ready().then(() => {
Deeplinks.routeWithNavController(this.nav, {
'/about-us': AboutPage,
'/hats/:hatId': HatDetailPage
});
});
}
});
ionicBootstrap(MyApp);
Note that although this improves the plugin interfacing a bit, it does not change the fact that you have to use some other mechanism to handle deep links in conjunction with your web app.
I need a web and mobile application which will work on android, iphone and windows as well.
I want to use facebook login for my apps and customer can like my page after login thats why i am using cordova to convert my web app into android app but i need to integrate facebook-like option which i didn't get in plugin.
So i implemented this using oglike
$scope.facebookLike = function() {
if($localStorage.hasOwnProperty("accessToken") === true) {
$http.post("https://graph.facebook.com/me/og.likes?access_token="+$localStorage.accessToken+"&object=https://www.facebook.com/Nxtlife-Technologies-Ltd-UK-180614345644169/?ref=br_rs");
alert("like sucessfully done");
} else {
alert("Not signed in");
$scope.facebookLogin();
}
}
Problem:
The code will not throwing any error but after success message it didin't make any changes to my page. like count is remains same.
og.likes is for Open Graph objects – external URLs, outside of Faceook.
You can not like Facebook pages by any other means than the official Like button.
I have an HTML5 application that uses Azure mobile services authentication to login (straight from the example code...provided below). It works fine in all desktop browsers and iPhone 5 in Safari. But from app / full screen mode, it does nothing (doesn't ask for permission to show a popup window like it does in safari and no popup windows shows up) and I can wait forever and nothing happens. If I invoke it a second time, it gives an error saying "Error: Unexpected failure"...perhaps because the 1st attempt is still running? Any help/insight is appreciated.
client.login ("facebook").done(function (results) {
alert("You are now logged in as: " + results.userId);
}, function (err) {
alert("Error: " + err);
});
edited update with more info and 2 potential ideas*
I did some more research and found a site that uses an approach that overcomes this problem and also solves two other side effects with the current Azure mobile approach to authentication. I think the Azure mobile team might be looking to do something similar because there are some hints of other authentication options in the code (although difficult to read and be sure because the minimized code is obsfucated). It might be just a matter of activating these in the code...
The "solution":
Go to http://m.bcwars.com/ and click on the Facebook login. You'll see it works perfectly in iPhone Safari in "app mode" becuase instead of doing a popup, it simply stays in the current browser window.
This approach solves two other problems with the current Azure mobile approach. First, the popup gets interpreted by most browsers as a potential ad and is either blocked automatically (desktop Chrome) ... and the user doesn't know why it's not working...or gives a warning which the user has to approve (iPhone Safari in "browser mode") which is a hassle. And if the user has a popup blocker, it gets more difficult and even more potential for the user not getting it to work properly. The bcwars.com method doesn't have this problem.
Second, in iPhone Safari, when the popup window auto closes, the original page doesn't get focus if there are other browser windows open in Safari. Instead, it's in the smaller/slide mode so they can choose which one to show. If this happens, the user has to go through one more sttep...click on the browser window to activate it and give it focus..again more of a pain and more potential for them to mess up and not do it correctly and need help. The m.bcwars.com doesn't have this problem.
Azure options:
Looking at the Azure mobile code it looks like may already have the solution. I can't read it easliy becuase it's minified/obsfucated, but it seems to have 4 options (including iFrame, etc.) for invoking the authentication, and only 1 (the "less ideal one" of a popup) is being used. An easy solution would be to set a property to allow one of the alternate authentications to work. But I can't read it well enough to figure it out. Another would be to hack the code (temporarily until a fix is put up by Microsoft).
Could I get some help there perhaps?
You can implement an authentication flow with Facebook that doesn't use a popup. The basic idea is to use the 'Web Flow' for doing the login, and once the window return from the login, use the access token to login the user in to Azure Mobile Services.
The Facebook documentation for doing this is here:
https://developers.facebook.com/docs/facebook-login/login-flow-for-web-no-jssdk/#step2
Some code samples to make it easier for you.
You would start by something like this:
(Remember to replace YOUR_APP_ID and YOUR_URL with something relevant to your site.
function logIn() {
window.location.replace('https://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_uri=http%3A%2F%2FYOUR_URL&response_type=token')
}
This redirects the window to the Facebook page for the user to log in and authorize your app. When the user is done, Facebook will redirect the user back to YOUR_URL given above.
There you can handle the redirect and do the Mobile Services Login with something like this:
function handleLoginResponse() {
var frag = $.deparam.fragment();
if (frag.hasOwnProperty("access_token")) {
client.login("facebook", { access_token: frag.access_token }).then(function () {
// you're logged in
}, function (error) {
alert(error);
});
}
}
In here you parse the access token you get as a URL fragment and pass it as argument to the login call you make to Azure Mobile Services.
This code depends on the jquery BBQ plugin to handle the URL fragment easily.
Hope this solves your problem!