I have a Xamarin.Android project where I want to use Xamarin.Auth package to let user authenticate through Google sign-in page.
Here is my code at MainActivity.cs
OAuth2Authenticator auth = new OAuth2Authenticator
(
clientId: "client-id.apps.googleusercontent.com",
scope: "",
authorizeUrl: new Uri("https://accounts.google.com/o/oauth2/v2/auth"),
redirectUrl: new Uri("http://www.facebook.com/connect/login_success.html"),
// switch for new Native UI API
// true = Android Custom Tabs and/or iOS Safari View Controller
// false = Embedded Browsers used (Android WebView, iOS UIWebView)
// default = false (not using NEW native UI)
isUsingNativeUI: false
);
auth.Completed += (sender, eventArgs) =>
{
// UI presented, so it's up to us to dimiss it on Android
// dismiss Activity with WebView or CustomTabs
this.Finish();
if (eventArgs.IsAuthenticated)
{
// Use eventArgs.Account to do wonderful things
}
else
{
// The user cancelled
}
};
var ui_object = auth.GetUI(this);
StartActivity(ui_object);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
I allways ends up with folowing exception when calling auth.GetUI(this) method:
JNIEnv.FindClass(Type) caught unexpected exception: Java.Lang.ClassNotFoundException: md53c585be971e02235139fd1aef11fc0c1.WebAuthenticatorActivity ---> Java.Lang.ClassNotFoundException: Didn't find class "md53c585be971e02235139fd1aef11fc0c1.WebAuthenticatorActivity"
Can anyone see why it would do this? I've tried to google it but looks like I'm only one who gets this type of error.
I have VS 2017 15.5.2 and using Android 8.0 API 26
Solved! I remove/add my nuget packages to Xamarin.Auth and PCLCrypto and everything is working now. Google sign-in page is displayed when app starts.
Related
I have the current workflow for my authentication
User signs in via google OAuth2
User is then given a server_auth_code which they send to my backend authentication
The auth code is validated on the back end and users is sent a JWT
I had this all working in raw Java with the Android SDK, but Flutter seemed a lot nicer. But now when using the google_sign_in plugin on android, I am unable to retrieve the serverAuthCore anymore, this plugin just wants to return null the entire time.
I Am using the client ID that's specified for Android, however, I tested the WebApplication that's auto-generated by google too but that's the same issue (Null serverAutHCode)
This is the code that I am currently using:
/// Provides the `GoogleSignIn` class
import 'package:google_sign_in/google_sign_in.dart';
class GoogleLoginPage extends StatefulWidget {
final String name = "Logging in with google.";
late GoogleSignIn _googleSignIn;
GoogleLoginPage() : super() {
_googleSignIn = GoogleSignIn(
scopes: ['https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/userinfo.profile'],
serverClientId: "XX-XXX.apps.googleusercontent.com"
);
}
Future<void> fetchAuthToken() async {
try {
var response = await _googleSignIn.signIn();
log(response?.serverAuthCode ?? "No server auth code");
_googleSignIn.signOut();
} catch (error) {
print("ERR");
print(error);
}
}
#override
State<GoogleLoginPage> createState() => GoogleLoginState();
}
The output of this code is: [log] No server auth code
The question:
Am I doing something wrong? As mentioned this works 100% on my java project using the google play services SDK so I know it's nothing to do with my google console configurations.
Okay so I figured out the issues:
It appears that by default the google login plugin for flutter comes on an older version (If I remember correctly it was 20.0.5)
I Simply changed the version to the latest version:
'com.google.android.gms:play-services-auth:20.2.0'
You can do this by editing the project's build.gradle (In IntelliJ you open build.gradle and click "Open for editing in the android studio" in the top right, from there you need to find the gradle file for google_sign_in, and change the import there, remember to click sync in the top right of android studio before you close out of it)
And I began to receive my serverAuthCode as normal, cheers!
When using MOBILE SHARE (navigator.share), canceling the Share flow causes an unexpected error to appear.
The message can be acknowledged and user is allowed to proceed but this error response is unexpected.
STEPS TO REPLICATE
1.Tap the SHARE icon to initiate the share dialog then:
2.a on iOS, find and tap the close [ x ] control in the upper righthand corner of the dialog to dismiss
2.b on Android, swipe the share overlay down (or whatever way to close/exit this dialog?)
3.The error "AbortError: About due to cancellation of share" appears when:
on iOS, immediately on cancellation
on Android, when attempting to re-engage the Share control.
The error message:
www.example.com says: AbordError: Share canceled
Im using this Vue plugin https://github.com/GabrielBibiano/vue-navigator-share
This is not an issue with Vue.js or any plugin, but something that navigator.share function does.
It is throwing this on canceling/dismissing share action.
Check this example on phone which supports navigator.share.
(NOTE: open this page as desktop site since phones can not run examples)
You can also see this (LOC: 303): https://chromium.googlesource.com/chromium/src/+/34eacf936ac3255925c5045c4385dc9b5f19fa78/chrome/android/javatests/src/org/chromium/chrome/browser/webshare/WebShareTest.java
const share = async () => {
try {
await navigator.share({ url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ' });
} catch (e) {
if (e.toString().includes('AbortError')) {
alert('Hello world aborted :(');
}
}
}
<button onclick="share()">share (only for phones)</button>
I am currently developing an Android application using Cordova. This working fine so far, but now that I want to add a Chromecast button to the UI, it does not seem to work. I followed the instructions provided here: https://developers.google.com/cast/docs/chrome_sender/integrate
And this is what my code looks so far:
var CastPlayer = function() {
//...
/* Cast player variables */
/** #type {cast.framework.RemotePlayer} */
this.remotePlayer = null;
/** #type {cast.framework.RemotePlayerController} */
this.remotePlayerController = null;
//...
};
var castPlayer = new CastPlayer();
window['__onGCastApiAvailable'] = function(isAvailable) {
if (isAvailable) {
castPlayer.initializeCastPlayer();
}
};
Inline script inside my index.html.
CastPlayer.prototype.initializeCastPlayer = function() {
var options = {};
// Set the receiver application ID to your own (created in the
// Google Cast Developer Console), or optionally
// use the chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID
options.receiverApplicationId = chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID;
// Auto join policy can be one of the following three:
// ORIGIN_SCOPED - Auto connect from same appId and page origin
// TAB_AND_ORIGIN_SCOPED - Auto connect from same appId, page origin, and tab
// PAGE_SCOPED - No auto connect
options.autoJoinPolicy = chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED;
cast.framework.CastContext.getInstance().setOptions(options);
this.remotePlayer = new cast.framework.RemotePlayer();
this.remotePlayerController = new cast.framework.RemotePlayerController(this.remotePlayer);
this.remotePlayerController.addEventListener(
cast.framework.RemotePlayerEventType.IS_CONNECTED_CHANGED,
this.switchPlayer.bind(this)
);
};
Content of my index.js.
In the index.html, I added the button like this:
<google-cast-launcher id="castbutton"></google-cast-launcher>
Now when I open my Cordova app via browser (Chrome AND Chromium), the cast button shows and I can use it normally. When I open the App on Android, the Button just does not show. Does anybody know what causes this and if it can be resolved?
We could not find a solution for Cordova, but managed it in Flutter.
We had the same challenge, and we searched high and low. Finally found this solution to make it work with: https://pub.dev/packages/dart_chromecast
Make sure your flutter compiler is downgraded to 13 or below. Otherwise, you will not be able to compile. Unfortunately, their code is not supported in a newer version of the flutter compiler and the author is not going to update anytime soon.
Click here to view screenshot here
I am using react native app auth with Azure active directory and in android after redirecting back to the app, two apps are shown (like in the above screenshot) , if i select the correct app the app works as expected, but if i select the other, the app crashes. How can i fix this issue and show only one app!
const config = {
issuer: 'https://login.microsoftonline.com/your-tenant-id',
clientId: 'your-client-id',
redirectUrl: 'urn:ietf:wg:oauth:2.0:oob',
scopes: [], // ignored by Azure AD
additionalParameters: {
resource: 'your-resource'
}
};
// Log in to get an authentication token
const authState = await authorize(config);
// Refresh token
const refreshedState = await refresh(config, {
refreshToken: authState.refreshToken,
});
Try not to put "scheme" option into app.json and use a redirectUrl like this.
<your.package.identifier>://oauthredirect
According to this AppAuth OAuthRedirect, AppAuth uses for scheme the android.package identifier. For example if your package.identifier is "your.company.app", use a redirectUrl like this: your.company.app://oauthredirect. It works for me.
I'm building a Cordova Ionic application which fetches JSON response on button click and display it. It's working fine in browser but it's not displaying anything in android.
angular.module('starter', ['ionic'])
.config(function($ionicConfigProvider) {
$ionicConfigProvider.navBar.alignTitle('center'); //align title in center
})
.controller('ControllerOne',[ '$scope', 'freshlyPressed', Ctrl])
.service('freshlyPressed', ['$http','$log', freshlyPressed]);
function Ctrl($scope, freshlyPressed){
$scope.refreshClicked = function(){
freshlyPressed.getBlogs($scope);
}
};
function freshlyPressed($http,$log){
this.getBlogs = function($scope){
$http.jsonp("https://public-api.wordpress.com/rest/v1.1/freshly-pressed?callback=JSON_CALLBACK")
.success(function(result, posts){
$scope.posts = result.posts;
});
};
};
How would I know if any exception occurred while testing the app in android?
[Edit] I'm new to Android & Cordova.
The only way you can find out if something goes wrong is if you add a .error function after the .success function, otherwise errors will not be caught.
Here is a code example for your current situation:
function freshlyPressed($http,$log){
this.getBlogs = function($scope){
$http.jsonp("https://public-api.wordpress.com/rest/v1.1/freshly-pressed?callback=JSON_CALLBACK")
.success(function(result, posts){
$scope.posts = result.posts;
})
.error(function(error){
console.log(error);
});
};
};
Although, I would highly recommend you switch to the .then() function, as .error and .success have been deprecated as described here.
You can debug your android apps with Chrome using DevTool.
To enable Remote Debugging follow these Remote Debugging Devices Documetation
.
To use it follow Chrome Inspector (Ionic Docs).
Hope this may help you.