Xamarin FacebookClient - android

I am using Xamarin Forms and want to integrate Facebook in android app. I want to pull the feed from a page like https://www.facebook.com/HyundaiIndia
I have installed Xamarin.Facebook from Nuget. It doesn't have a FacebookClient object as mentioned in here: https://components.xamarin.com/gettingstarted/facebook-sdk
Then I found the Xamarin.Facebook and Xamarin.FacebookBolts namespaces which I included, but I still didn't get FacebookClient. Instead I found Xamarin.Facebook.XAndroid.Facebook and I created an instance:
Xamarin.Facebook.XAndroid.Facebook fb = new Xamarin.Facebook.XAndroid.Facebook(FacebookAppId);
But this object doesn't have GetTaskAsync. How do I pull down the feeds in Xamarin?

I had the same experience trying following the article you mentioned.
The component created by Outercurve Foundation (Facebook.dll version 6.2.1)
needs that you reference Facebook.dll and you include it in your file like this:
using Facebook;
Don't confuse it with:
using Xamarin.Facebook;
EDIT
I finally found a bit of time for a more complete answer and since the example on the link
doesn't specify how to obtain the AccessToken (called userToken in the facebook-sdk component page example linked in the question) I'm posting one of the possible solutions.
This one works for me and doesn't require any other library or component (but the one already mentioned in the question).
using Xamarin.Auth;
using Facebook;
string FaceBookAppId = "YOUR_FACEBOOK_APP_ID";
string AccessToken;
string OauthTokenSecret;
string OauthConsumerKey;
string OauthConsumerSecret;
void GetFBTokens()
{
var auth = new OAuth2Authenticator(FaceBookAppId,
"",
new Uri("https://m.facebook.com/dialog/oauth/"),
new Uri("https://www.facebook.com/connect/login_success.html")
);
auth.Completed += (sender, eventArgs) =>
{
if (eventArgs.IsAuthenticated)
{
eventArgs.Account.Properties.TryGetValue("access_token", out AccessToken);
eventArgs.Account.Properties.TryGetValue("oauth_token_secret", out OauthTokenSecret);
eventArgs.Account.Properties.TryGetValue("oauth_consumer_key", out OauthConsumerKey);
eventArgs.Account.Properties.TryGetValue("oauth_consumer_secret", out OauthConsumerSecret);
}
};
}
//Now we can use the example of the link.
void PostToMyWall ()
{
FacebookClient fb = new FacebookClient (AccessToken);
string myMessage = "Hello from Xamarin";
fb.PostTaskAsync ("me/feed", new { message = myMessage }).ContinueWith (t => {
if (!t.IsFaulted) {
string message = "Great, your message has been posted to you wall!";
Console.WriteLine (message);
}
});
}

There are 2 editions of Facebook SDK, one is binding for official SDK, another is from Outercurve Foundation.
Looks like you're using this one: the "official" binding , so check the documentation on this link.

Related

Using Google to sign into my app using Xamarin Forms and Xamarin.Auth

I have scoured the web trying to get an answer for this and I have found many but none of them work. Google requires that the authentication happens in the browser and not in a WebView. I have implemented it like this for Android:
var activity = this.Context as Activity;
var auth = new OAuth2Authenticator(
clientId: "xxxx.apps.googleusercontent.com",
scope: "",
authorizeUrl: new Uri("https://accounts.google.com/o/oauth2/auth"),
redirectUrl: new Uri("myredirecturi"));
auth.Completed += (sender, eventArgs) => {
if (eventArgs.IsAuthenticated)
{
App.SuccessfulLoginAction.Invoke();
App.SaveToken(eventArgs.Account.Properties["access_token"]);
}
};
activity.StartActivity(auth.GetUI(activity));
And like this for iOS:
var auth = new OAuth2Authenticator(
clientId: "xxxx.apps.googleusercontent.com", // your OAuth2 client id
scope: "",
authorizeUrl: new Uri("https://accounts.google.com/o/oauth2/auth"),
redirectUrl: new Uri("myredirecturi"));
auth.Completed += (sender, eventArgs) =>
{
App.SuccessfulLoginAction.Invoke();
if (eventArgs.IsAuthenticated)
{
App.SaveToken(eventArgs.Account.Properties["access_token"]);
}
PresentViewController(auth.GetUI(), true, null);
};
But this does exactly what I don't want it to do (opens a WebView) and every single answer I have found does exactly this. How do I go about doing it correctly so that the browser opens and then returns to my app when it is done?
Furthermore, I know the scope specifies what I want to do, and in this case it is just a sign-in, but I have yet to find an example of what to actually put in there.
Any example will be really appreciated.
You need to specifically enable the native UI type of authentication. So add the following to your OAuth2Authenticators in each project:
new OAuth2Authenticator {
isUsingNativeUI = true
}
Also make sure you are using at least version 1.5.0+ to get this property.

What does Device Id mean Azure Push Notifications in Xamarin Android? How to get it?

We are using Azure Mobile Services to Push notifications to a Xamarin Android and a Xamarin iOS and a Windows Universal App. The Windows Universal App has plenty of documentation around what we need, although we haven’t had a chance to implement it yet. However, both Xamarin Android and iOS are missing all documentation around Push Notifications. If you go to http://azure.microsoft.com/en-us/documentation/services/mobile-services/ and select Xamarin Android or Xamarin iOS and .NET Backend there are zero links for documentation around these APIs. After digging around a ton yesterday I found this: http://azure.microsoft.com/en-us/documentation/articles/mobile-services-dotnet-backend-xamarin-android-get-started-push/ and http://azure.microsoft.com/en-us/documentation/articles/mobile-services-dotnet-backend-xamarin-ios-get-started-push/ both which were last updated in September of last year. The documentation was promised to be updated over 5 months ago.
When I use the Xamarin Component from Microsoft for Azure Mobile Services: http://components.xamarin.com/view/azure-mobile-services/ I am able to get the MobileServiceClient up and running, but not the Push notifications.
The API:
Push pushManager = MobileService.GetPush();
string deviceId = "what is this???";
//Option 1:
pushManager.RegisterNativeAsync(deviceId);
//Option 2:
GcmRegistration googleNotificationRegistration = new GcmRegistration(deviceId);
pushManager.RegisterAsync(googleNotificationRegistration);
Documentation I’m using:
Push.RegisterAsync:
https://msdn.microsoft.com/en-us/library/microsoft.windowsazure.mobileservices.push.registerasync.aspx
GcmRegistration: I can’t find any documentation for this class
Registration (Base class for GcmRegistration):
https://msdn.microsoft.com/en-us/library/microsoft.windowsazure.mobileservices.registration.aspx
Note: the parameter for Registration is not named deviceId it is named channelUri
Push.RegisterNativeAsync:
https://msdn.microsoft.com/en-us/library/dn643553.aspx
Note: the parameter of RegisterNativeAsync is not named deviceId it is named channelUri
My question is simple:
What is deviceId supposed to be? And how do I get it?
All the documentation above is for Winodws Universal Apps not for Xamarin Apps on Mono.
In the writing up of this question I have found articles about "Get Started with Notification Hubs":
Xamarin iOS - http://azure.microsoft.com/en-us/documentation/articles/partner-xamarin-notification-hubs-ios-get-started/
Xamarin Android - http://azure.microsoft.com/en-us/documentation/articles/partner-xamarin-notification-hubs-android-get-started/
Are these the example I should be using? They look old and the Android one mentions nothing about Azure Mobile Services. Should I not even be using the Azure Mobile Services Xamarin Component for Android?
tl;dr
deviceId should be just the GCMRegistrationId.
I looked into the source code of the implementations of the component DLLs and also Android SDKs.
Firstly, let's take a look to your option 1 and option 2 behind the scene. Basically both eventually do the same job of creating a GcmRegistration and passing it the internal RegistrationManager.
public Task RegisterAsync (Registration registration)
{
if (registration == null) {
throw new ArgumentNullException ("registration");
}
if (string.IsNullOrWhiteSpace (registration.PushHandle)) {
throw new ArgumentNullException ("registration.deviceId");
}
return this.RegistrationManager.RegisterAsync (registration);
}
public Task RegisterNativeAsync (string deviceId, IEnumerable<string> tags)
{
if (string.IsNullOrWhiteSpace (deviceId)) {
throw new ArgumentNullException ("deviceId");
}
GcmRegistration registration = new GcmRegistration (deviceId, tags);
return this.RegistrationManager.RegisterAsync (registration);
}
Then, one of the API calls that I can find involving the Registration.PushHandle (which is the deviceId you passed) is as below
public async Task<IEnumerable<Registration>> ListRegistrationsAsync (string deviceId)
{
MobileServiceHttpResponse mobileServiceHttpResponse = await this.client.HttpClient.RequestAsync (HttpMethod.Get, string.Format ("/push/registrations?deviceId={0}&platform={1}", new object[] {
Uri.EscapeUriString (deviceId),
Uri.EscapeUriString (Platform.Instance.PushUtility.GetPlatform ())
}), this.client.CurrentUser, null, true, null, MobileServiceFeatures.None);
return JsonConvert.DeserializeObject<IEnumerable<Registration>> (mobileServiceHttpResponse.Content, new JsonConverter[] {
new RegistrationConverter ()
});
}
I have then switched to Android Mobile Services SDK to look for similar code to find some hints. Sadly, it is found called pnsHandle in android but still no hints what it is.
/**
* Registers the client for native notifications with the specified tags
* #param pnsHandle PNS specific identifier
* #param tags Tags to use in the registration
* #return The created registration
* #throws Exception
*/
public Registration register(String pnsHandle, String... tags) throws Exception {
if (isNullOrWhiteSpace(pnsHandle)) {
throw new IllegalArgumentException("pnsHandle");
}
Registration registration = PnsSpecificRegistrationFactory.getInstance().createNativeRegistration(mNotificationHubPath);
registration.setPNSHandle(pnsHandle);
registration.setName(Registration.DEFAULT_REGISTRATION_NAME);
registration.addTags(tags);
return registerInternal(registration);
}
Finally, I guess the below example code from http://azure.microsoft.com/en-us/documentation/articles/mobile-services-dotnet-backend-android-get-started-push/#update-app should be calling the same API which now explain everything, i.e. deviceId is just the GCMRegistrationId.
#Override
public void onRegistered(Context context, final String gcmRegistrationId) {
super.onRegistered(context, gcmRegistrationId);
new AsyncTask<Void, Void, Void>() {
protected Void doInBackground(Void... params) {
try {
ToDoActivity.mClient.getPush().register(gcmRegistrationId, null);
return null;
}
catch(Exception e) {
// handle error
}
return null;
}
}.execute();
}

AxSU3D Android Facebook Plugin - "The parameter app_id is required"

I'm using AxSU3D's Android plugin in a Unity project. When I try to use the Facebook Login method, I get an error that says "The parameter app_id is required"
I have posted my code below. I have REPLACED the string "fbAppID" with the actual ID. This is just the sample script that came with the plugin that I am trying to use.
Any help will be appreciated
using UnityEngine;
using System.Collections;
using AxSAndroidPlugin.Core;
using AxSAndroidPlugin.Social.Facebook;
public class FacebookSample : MonoBehaviour {
public string fbAppID = "YOUR_FACEBOOK_APP_ID_HERE";
public GameObject picture;
//Texture2D tex;
void OnGUI () {
if(GUI.Button(GUIControls.GetButtonRect(1), "Init" ))
Facebook.Init(fbAppID);
if(GUI.Button(GUIControls.GetButtonRect(2), "Login" ))
Facebook.Login();
if(GUI.Button(GUIControls.GetButtonRect(3), "IsLoggedIn"))
Facebook.IsLoggedIn();
if(GUI.Button(GUIControls.GetButtonRect(4), "User Info")) {
Facebook.GetUserInfo();
}
if(GUI.Button(GUIControls.GetButtonRect(5), "Friends")) {
Facebook.GetFriendsList();
}
if (GUI.Button (GUIControls.GetButtonRect (6), "Load Profile Picture")) {
Facebook.LoadProfilePicture();
}
if (GUI.Button (GUIControls.GetButtonRect (7), "Get Profile Picture")) {
Texture2D tex = Facebook.GetProfilePicture();
picture.renderer.material.mainTexture = tex;
}
if(GUI.Button(GUIControls.GetButtonRect(8), "Send Request")) {
Facebook.SendRequest("This Plugin Rocks!");
}
if(GUI.Button(GUIControls.GetButtonRect(9), "Post To Timeline")) {
string name = "AxS Android Plugin";
string caption = "AxS Android Plugin for Unity";
string description = "A complete solution to all your Android native needs!";
string link = "http://www.axsu3d.com/";
string pictureLink = "http://www.axsu3d.com/DLs/axsu3dLogo.png";
Facebook.PostToTimeline(name, caption, description, link, pictureLink);
}
//Get the user's likes
if(GUI.Button(GUIControls.GetButtonRect(10), "User Likes")) {
Facebook.GetUserLikes();
}
//Logout of Facebook
if(GUI.Button(GUIControls.GetButtonRect(11), "Logout" ))
Facebook.Logout();
if(GUI.Button(GUIControls.GetButtonRect(12), "Back"))
Application.LoadLevel("CoreSample");
}
}
Firstly, wow. I didn't realize something I helped make would show up on SO.
The solution is quite simple, really. You probably did not use the "Merge Manifest" option.
You can find this option under "Tools/AxSU3D/Android/Merge Manifest". This will show a window where you can put in your Facebook app ID.
The option will create or merge a new AndroidManifest.xml file, which will also contain your Facebook App ID.
Try it out.

How to use HttpWebRequest with async & await

I am new to Xamarin and C# as well. I try to make a Http request to my server with some information.
In general with android Native a uses AsyncTask and HttpClient for that. and build a json object or name value pair, and encrypt it to integrate information with the request.
But when I try to do the same with xamarin I get some problems.
if I try to import the namespace
using System.Net.Http.HttpClient
than my xamarin not have this namespace
Because of the above problem I try to use HttpWebRequest. But when I go for use it with the asyc and await I am not getting any response from server.
I am new to xamarin so I am not sure about async and await keyword.
I read lot of articles but No luck :(
on Click of the Button I call the below Method
public async Task<int> ValidateUser(){
try{
var request = HttpWebRequest.Create (URL);
request.Method = "GET/POST";
String postString = String.Format ("AAA ={0}&BBB={1}&CCC={2}", "111",
"222","333");
byte[] postByte = Encoding.UTF8.GetBytes (postString);
Stream st = request.GetRequestStream ();
//I am reaching here
Console.WriteLine("Check for Validity");
request.ContentLength = postByte.Length;
st.Write (postByte, 0, postByte.Length);
st.Close ();
Task<Stream> contentTask = request.GetRequestStreamAsync();
Stream response = await contentTask;
String str = response.ToString();
// this is not getting printed in Console
Console.WriteLine("=====>>"+str);
}
catch (WebException exception) {
string responseText;
using (var reader = new StreamReader(exception.Response.GetResponseStream())) {
responseText = reader.ReadToEnd ();
Console.WriteLine ("====Dude Error"+responseText);
}
}catch(Exception e){
}
return 1;
}
Any help will be appreciated
Consider using RestSharp, a component created for Xamarin to facilitate web requests. Click here for more info on the component. It will facilitate allot of things about webrequesting ( like serialization, automatic return type detection,... )
Your code would look something like this with restsharp:
public async Task<int> ValidateUser(){
var client = RestClient (URL);
var request = new RestRequest ("AAA ={0}&BBB={1}&CCC={2}", "111",
"222","333");
client.ExecuteAsync (request, response => {
WebApiResponse webApiResponse = new WebApiResponse ();
webApiResponse.Content = response.Content;
webApiResponse.StatusCode = response.StatusCode;
webApiResponse.ResponseStatus = (WebApiResponseStatus)response.ResponseStatus;
return webApiResponse.Content;
});
return -1
}
Using HttpWebRequest is a bad idea, instead it would be better to focus on why you don't have the System.Net.Http.* namespace. Imho the most likely cause is that you didn't add System.Net.Http as a reference to your project.
Here's how you add System.Net.Http.* to your project.
In Visual Studio 2013:
Open the solution
Open the project
Open the Solution Explorer
Right-click on References
Add Reference
Click on 'Search Assemblies'
Type in 'Http'
Select System.Net.Http
Press 'OK'
In Xamarin Studio:
Open the solution
Open the project
Open the Solution Explorer
Right-click on References
Edit References
Type in 'Http'
Select System.Net.Http
Press 'OK'
Afterwards there should be no problems resolving System.Net.Http when 'using System.Net.Http;'

Upload picture to facebook from unity

Im working on a unity game where you can take a picture and upload this picture to facebook from unity along with some tags and stuff (much like friendsmash). The problem is that i do not have a web-server that i can put the screenshots on, and the Fb.Feeb(picture:) attribute only accepts urls.
I have read that you can use HTTP POST to post the picture to the users images and then use that link in picture:, but i dont know anything about HTTP POST and i couldnt figure out how to do it.
I have also read that you can use FB.API() to somehow do this, but i couldnt figure it out.
Any sample code would be greatly appreciated.
My current code:
private string _path = "file://" + System.IO.Path.Combine(Application.persistentDataPath, "Images/image.png");
void Start ()
{
if (!FB.IsLoggedIn)
FB.Login("email, publish_actions, publish_stream, user_photos", LoginCallback);
StartCamera();
}
private void OnBragClicked()
{
FbDebug.Log("OnBragClicked");
//Post(); <-- dont know how
FB.Feed(
linkCaption: "#hashtag",
picture: "???",
linkName: "Im hashtaging!",
link: "https://apps.facebook.com/" + FB.AppId + "/?challenge_brag=" + (FB.IsLoggedIn ? FB.UserId : "guest")
);
}
void TakeSnapshot()
{
_snap = new Texture2D(_webCamTexture.width, _webCamTexture.height);
_snap.SetPixels(_webCamTexture.GetPixels());
_snap.Apply();
//System.IO.File.WriteAllBytes(_path, _snap.EncodeToPNG());
}
The facebook sdk does have a way to make this happen after all. You need to use Fb.API().
This is the way it worked for me:
private void TakeScreenshot()
{
var snap = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
snap.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
snap.Apply();
var screenshot = snap.EncodeToPNG();
var wwwForm = new WWWForm();
wwwForm.AddBinaryData("image", screenshot, "barcrawling.png");
FB.API("me/photos", HttpMethod.POST, LogCallback, wwwForm);
}
In general terms, to add some sort of caption, it's along the lines...
private byte[] postcardAsBytes;
string textMessage = "Play this great game at http://blah.com.";
Dictionary<string, object> d = new Dictionary<string, object>
{
{ "message", textMessage },
{ "picture", postcardAsBytes }
};
Facebook.instance.graphRequest(
"me/photos", HTTPVerb.POST, d, yourCompletionHandler);
// in this example using the prime31 plugin, rather than the fb sdk
The key field seems to be "message". Confusingly, the "dictionary" field documented by FB, seems to just not work, so try "message" at first.

Categories

Resources