.Net Maui Android app how to get email and profile from Google login - xamarin.android

I tried WebAuthenticator and it doesn't work.
I also tried using the deprecated GoogleApiClient with this method and the value is always null.
var person = PlusClass.PeopleApi.GetCurrentPerson(mGoogleApiClient)
I even tried adding email and profile scopes to my Google Fit Auth, but I can't get the email, profile etc...
I just tried this method, and it doesn't work either.
mSignInClient = GoogleSignIn.GetClient(this, options);
At this point, I'm stuck. Does anyone know how to get the user and profile information for the logged in user on a .Net Maui Android app???
Thanks!

I finally got this working by creating my own LoginActivity.
https://developers.google.com/identity/sign-in/android/sign-in
I'm calling the Activity using this code. It's running in an OnButtonClicked override in the LoginPage.xaml.cs file.
#if ANDROID
var myIntent = new Android.Content.Intent(Platform.CurrentActivity, typeof(LoginActivity));
Platform.CurrentActivity.StartActivityForResult(myIntent, 0);
#endif
Finally, the OnCreate method in the LoginActivity calls SignOn() after this line of code executes.
mGoogleSignInClient = GoogleSignIn.getClient(this, gso);

Related

Did anyone manage to get the id token from google sign in (Flutter)

I am trying to connect my users with my back end server , i used the example from the official google sign in plugin for flutter :
https://pub.dartlang.org/packages/google_sign_in
the sign process goes fine and i get the username and email ect..
but i need the id Token to authenticate the user with my server.
Ps: Not using firebase , only google sign in.
Can anyone guide me how to get the id Token ?
You can try using this
_googleSignIn.signIn().then((result){
result.authentication.then((googleKey){
print(googleKey.accessToken);
print(googleKey.idToken);
print(_googleSignIn.currentUser.displayName);
}).catchError((err){
print('inner error');
});
}).catchError((err){
print('error occured');
});
You can get access token and id token more simple like this:
final result = await _googleSignIn.signIn();
final ggAuth = await result.authentication;
print(ggAuth.idToken);
print(ggAuth.accessToken);
Or you also can add it to try-catch to handle an error.
try {
final result = await _googleSignIn.signIn();
final ggAuth = await result.authentication;
print(ggAuth.idToken);
print(ggAuth.accessToken);
} catch (error) {
print(error);
}
or try like this if id token was null, it worked for me.
As the docs point out you need oauth2 client id of your backend to request idToken or serverAuthCode.
from firebase google sigin in authentication copy the Web SDK configuration
add paste in the following to res/values/strings.xml, That should work
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="default_web_client_id">{Web app Client id goes here}</string>
</resources>
The issue may be related to not using firebase. There is a google-services.json file which is given to you when you register your app in firebase, and you can use that with google_sign_in (this is the default way shown in the documentation).
I was getting null for the token value when trying to implement this without the google-services.json, but successfully signing into google.
If you don't want to use firebase, you have to jump through a couple hoops.
In google cloud console, register your app.
Then make sure you are 'in' your app that you just created in the top drop down menu.
in "apis and services" in the sidebar menu, go through the create Oauth consent screen menu, I don't remember having to fill out many fields, so leave them blank if you don't know what to put in.
then go to the "credentials" menu in the sidebar, and click "Create New Credentials", and select OAuth2 client ID. Make a web client, even though you're trying to use it with an android/ios app.
Make a file android/app/src/main/res/values/strings.xml
using the web client we just made, insert <?xml version="1.0" encoding="utf-8"?> <resources> <string name="default_web_client_id">YOUR WEB CLIENT ID</string> </resources> into the strings.xml file.
[edit] make one more client in the google console for android, and put in your local machine's sha1 key. This step is done for you automatically if you're using firebase. In this case, you have to create both the web client and one for your android device. In production, you'd be using a specific client for your production app.
That should do it I believe, might have missed a step.
I also wanted to verify on my backend that the incoming idtoken was valid, so I had to also make a service account (in the apis and services -> credentials page) and use that in my go server.
I'm still struggling to get this to work with ios, but the android side works great.
To retrieve the Is idToken worked for me:
1. The google-services.json file must be placed in /android/app/
2. you need to add to your /android/app/build.gradle
apply plugin: 'com.google.gms.google-services'
3. and to /android/build.gradle
classpath 'com.google.gms:google-services:4.3.4'
And that's it. GoogleSignIn will return a real idToken instead of null.
font: https://github.com/flutter/flutter/issues/12140#issuecomment-348720774
One more clean way to achieve this:
late Map<String, dynamic> userObject = {};
var res = await _googleSignIn.signIn();
var googleKey = await res!.authentication;
userObject.addAll({
'accessToken': googleKey.accessToken,
'idToken': googleKey.idToken,
'displayName': res.displayName ?? '',
'email': res.email,
'id': res.id,
'avatarUrl': res.photoUrl ?? '',
'serverAuthCode': res.serverAuthCode ?? '',
});
I was struggling with this issue for about a month. Turns out I was getting the same access token, even when the user tried restarting the app. This was painful because my app dealt with scopes and in case a user misses to check one or more scopes in his first sign in, the app wouldn't work at all, even if he/she signs in again and gives the permissions.
Workaround which worked for me: I called the googleSignIn.currentUser.clearAuthCache() method followed by googleSignIn.signInSilently(). This returns a GoogleSignInAccount which can be used for further authentication. My guess is that the clearAuthCache() method clears the token cache and hence a new token is created. This should get you a new access token and let your app make valid calls.
I sincerely request Google developers to solve this issue. For now, this workaround is the only thing that worked.
Try this:
When you create your GoogleSignIn object:
GoogleSignIn(
clientId: "YOUR CLIENT ID"
)
i hope it helps ;)

Changing CurrentAccessToken in Facebook Unity SDK

I'm trying to post to a Facebook page AS the page using the Unity Facebook SDK running on iOS. As I understand, to do that, I need the pages access token with manage_pages and publish_pages. I know that I can get it from /me/accounts?fields=access_token, but how do I tell AccessToken.CurrentAccessToken to use my pages access token instead?
Right now i'm using the following:
var wwwForm = new WWWForm();
//wwwForm.AddField ("access_token", "A-T I NEED");
wwwForm.AddBinaryData("image", screenshot, "InteractiveConsole.png");
wwwForm.AddField("message", "herp derp. I did a thing! Did I do this right?");
FB.API("/PAGE-ID/photos", HttpMethod.POST, HandleResult, wwwForm);
I tried putting the access token manually, but that didn't work (so I commented it out).
With this as it is I'm getting an error, telling me that I need publish_actions, wich is not correct since I'm not trying to post as the user. If I also get publish_actions the Post goes online, but is posted to the page as the user speaking. (User is also Admin)
Any Ideas ? Thanks!
So, I filed a bug report to facebook and as it turns out: "… at this time this functionality is not supported." Wich simply means there is now way to use the Page Access Token you acquired via the FB.API within the FB.API. And they are not going to tell you abot it in the documentation.
As a workaround I simply use a UnityWebRequest like this:
IEnumerator UploadToPage(byte[] screenshot) {
var wwwForm = new WWWForm();
wwwForm.AddField("message", "herp derp. I did a thing! Did I do this right?");
wwwForm.AddBinaryData("image", screenshot, "Test.png");
string url = "https" + "://graph.facebook.com/"+ PageID + "/photos";
url += "?access_token=" + PageAccessToken;
using (UnityWebRequest www = UnityWebRequest.Post(url, wwwForm))
{
yield return www.Send();
if (www.isError)
{
Debug.Log(www.error);
}
else
{
Debug.Log("Form upload complete!");
}
}
Debug.Log(url);
}

NHtmlUnit cannot submit button

I'm discovering about NHtmlUnit to build an application web. But when I try it with auto login to yahoo mail. But after I run code. I refresh the login page of Yahoo so nothing changed. Not logged.
Code:
NHtmlUnit.WebClient driver = new NHtmlUnit.WebClient();
driver.Options.JavaScriptEnabled = true;
driver.Options.ThrowExceptionOnScriptError = false;
driver.Options.ActiveXNative = true;
driver.Options.CssEnabled = true;
HtmlPage page = driver.GetHtmlPage("https://login.yahoo.com/config/login?");
HtmlForm form = page.GetFormByName("login_form");
HtmlTextInput user = (HtmlTextInput)form.GetInputByName("login");
HtmlPasswordInput pass = (HtmlPasswordInput)form.GetInputByName("passwd");
user.SetValueAttribute("my account");
pass.SetValueAttribute("my pass");
HtmlSubmitInput submitButton = (HtmlSubmitInput)page.GetElementByName(".save");
HtmlPage nextpage = (HtmlPage)submitButton.Click();
Please help me why. I write it on .NET MVC 4 C#. Thank you very much.
Only update below single line,due to which u may face class cast exception
HtmlButton submitButton = (HtmlButton)page.GetElementByName(".save");
The code is completely fine, and should works.
Probably the reason you think it is not, is that you check it by a wrong method!
One essential elements which makes a site (i.e. login.yahoo.com) see you as logged in user, is the cookies it provide to your browser/webdriver when you use login forms, so if you use the login procedure by an instance of NHtmlUnit.Webclient (i.e. driver) then you are only logged in inside the driver web client, not inside any other browser or client, even on the same machine.
I tried to add this as a comment, but I don't have enough reputations.

Feed link doesn't work

I'm using the Facebook PHP SDK to developp my app.
From this morning, when I publish an automatic post on a user's feed, everything is ok but the link doesn't work anymore... (no reaction on click)
Once the feed is published, the target of the link is "http://www.facebook.com/connect/uiserver.php?app_id=2711...site.com/annonce?a=62&response_type=code&display=page" (and doesn't work)
I replace the name of my website by mysite.com for this example
Here is my code :
$feed_message = utf8_encode("J'ai besoin de : ".$A_titre);
$feed_picture = "http://www.mysite.com/graph/icon.png";
$feed_link = "http://www.mysite.com/annonce?a=".$ins_id; // go to my website not app
$feed_linkname = utf8_encode($A_titre);
$feed_description = utf8_encode($me_firstname)." a besoin de...";
$result = $fb->api('/me/feed/','post',array('message'=>$feed_message,'picture'=>$feed_picture,'link'=>$feed_link,'name'=>$feed_linkname,'description'=>$feed_description));
Do you have any idea of what i can do to fix it ?
Thanks
I have the same problem. It seems that it's linked to the new "Enhanced Auth Dialog".
I deactivated it since the timeline is not ready anyway, and there's no more http://www.facebook.com/connect/uiserver.php?app_id= appended to the links on the user's wall.

Twitter O-Auth Callback url

I am having a problem with Twitter's oauth authentication and using a callback url.
I am coding in php and using the sample code referenced by the twitter wiki, http://github.com/abraham/twitteroauth
I got that code, and tried a simple test and it worked nicely. However I want to programatically specify the callback url, and the example did not support that.
So I quickly modified the getRequestToken() method to take in a parameter and now it looks like this:
function getRequestToken($params = array()) {
$r = $this->oAuthRequest($this->requestTokenURL(), $params);
$token = $this->oAuthParseResponse($r);
$this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
return $token;
}
and my call looks like this
$tok = $to->getRequestToken(array('oauth_callback' => 'http://127.0.0.1/twitter_prompt/index.php'));
This is the only change I made, and the redirect works like a charm, however I am getting an error when I then try and use my newly granted access to try and make a call. I get a "Could not authenticate you" error. Also the application never actually gets added to the users authorized connections.
Now I read the specs and I thought all I had to do was specify the parameter when getting the request token. Could someone a little more seasoned in oauth and twitter possibly give me a hand? Thank You
I think this is fixed by twitter by now or you might have missed to provide a default callback url in your application settings, which is required for dynamic callback url to work as mentioned by others above.
Any case, I got this working by passing the oath_callback parameter while retrieving the request token. I am using twitter-async PHP library and had to make a small tweak to make the library pass the callback url.
If you are using twitter-async, the change is below:
modified getRequestToken and getAuthenticateURL functions to take callback url as parameter
public function getRequestToken($callback_url = null)
{
$params = empty($callback_url) ? null : array('oauth_callback'=>$callback_url);
$resp = $this->httpRequest('GET', $this->requestTokenUrl, $params);
return new EpiOAuthResponse($resp);
}
public function getAuthenticateUrl($callback_url = null)
{
$token = $this->getRequestToken($callback_url);
return $this->authenticateUrl . '?oauth_token=' . $token->oauth_token;
}
And pass the callback url from your PHP code.
$twitterObj->getAuthenticateUrl('http://localhost/twitter/confirm.php');
#Ian, twitter now allows 127.0.0.1 and has made some other recent changes.
#jtymann, check my answer here and see if it helps
Twitter oauth_callback parameter being ignored!
GL
jingles
even me to was getting 401 error.. but its resolved..
during registering your application to twitter you need to give callback url...
like http://localhost:8080.
i have done this using java...
so my code is: String CallbackURL="http://localhost:8080/tweetproj/index.jsp";
provider.retrieveRequestToken(consumer,CallbackURL);
where tweetproj is my project name
and index.jsp is just one jsp page...
Hope this may helps u...
After the user authorizes the application on twitter.com and they return to your callback URL you have to exchange the request token for an access token.
Twitter does not honor the oauth_callback parameter and will only use the one specified in the registered application settings.
It also doesn't allow for 127.0.0.1 or localhost names in that callback, so I've setup http://dev.twipler.com which is setup for 127.0.0.1 in DNS so you can safely use;
http://dev.twipler.com/twitter_prompt/index.php

Resources