Facebook Share in ios.Xamarin - facebook

I'm trying to implement the Facebook share functionality in my little xamarin iOS app. I've already downloaded the latest version of Facebook iOS SDK from nuget, but I don't know how to use it. Is there anyone who has done that already , so he can send me some normal info on that ?
Much appreciated before hands :)

I have implemented share for twitter and fb .
iOS version
you can share using native social services from ios and if not available use
OAuth2Authenticator to get access token then post using FB graph
public void ShareViaSocial(string serviceType, string urlToShare)
{
socialKind = serviceType == "Twitter" ? SLServiceKind.Twitter : SLServiceKind.Facebook;
if (SLComposeViewController.IsAvailable(socialKind))
{
_socialComposer = serviceType == "Twitter" ? SLComposeViewController.FromService(SLServiceType.Twitter) : SLComposeViewController.FromService(SLServiceType.Facebook);
_socialComposer.AddUrl(new Uri(urlToShare));
viewController.PresentViewController(_socialComposer, true, () =>
{
_socialComposer.CompletionHandler += (result) =>
{
Device.BeginInvokeOnMainThread(() =>
{
viewController.DismissViewController(true, null);
if (result == SLComposeViewControllerResult.Done)
{ OnShare(this, ShareStatus.Successful); }
else
{ OnShare(this, ShareStatus.NotSuccessful); }
});
};
});
}
//If user doest have fb app and no credential for social services we use fb graph
else if (socialKind == SLServiceKind.Facebook)
{
var auth = new OAuth2Authenticator(
clientId: SharedConstants.FacebookLiveClientId,
scope: SharedConstants.FacebookScopes,
authorizeUrl: new Uri(SharedConstants.FacebookAuthorizeUrl),
redirectUrl: new Uri(SharedConstants.FacebookRedirectUrl));
viewController.PresentViewController((UIViewController)auth.GetUI(), true, null);
auth.AllowCancel = true;
auth.Completed += (s, e) =>
{
//hide the webpage after completed login
viewController.DismissViewController(true, null);
// We presented the UI, so it's up to us to dimiss it on iOS.
if (e.IsAuthenticated)
{
Account fbAccount = e.Account;
Dictionary<string, string> dictionaryParameters = new Dictionary<string, string>() { { "link", urlToShare } };
var requestUrl = new Uri("https://graph.facebook.com/me/feed");
var request = new OAuth2Request(SharedConstants.requestMethodPOST, requestUrl, dictionaryParameters, fbAccount);
request.GetResponseAsync().ContinueWith(this.requestResult);
}
else { OnShare(this, ShareStatus.NotSuccessful); }
};
auth.Error += Auth_Error;
}
//If user doest have twitter app and no credential for social services we use xanarub auth for token and call twitter api for sending tweets
else
{
var auth = new OAuth1Authenticator(
SharedConstants.TwitterConsumerKey,
SharedConstants.TwitterConsumerSecret,
new Uri(SharedConstants.TwitterRequestUrl),
new Uri(SharedConstants.TwitterAuth),
new Uri(SharedConstants.TwitterAccessToken),
new Uri(SharedConstants.TwitterCallBackUrl));
auth.AllowCancel = true;
// auth.ShowUIErrors = false;
// If authorization succeeds or is canceled, .Completed will be fired.
auth.Completed += (s, e) =>
{
// We presented the UI, so it's up to us to dismiss it.
viewController.DismissViewController(true, null);
if (e.IsAuthenticated)
{
Account twitterAccount = e.Account;
Dictionary<string, string> dictionaryParameters = new Dictionary<string, string>() { { "status", urlToShare } };
var request = new OAuth1Request(SharedConstants.requestMethodPOST, new Uri("https://api.twitter.com/1.1/statuses/update.json"), dictionaryParameters, twitterAccount);
//for testing var request = new OAuth1Request("GET",new Uri("https://api.twitter.com/1.1/account/verify_credentials.json "),null, twitterAccount);
request.GetResponseAsync().ContinueWith(this.requestResult);
}
else { OnShare(this, ShareStatus.NotSuccessful); }
};
auth.Error += Auth_Error;
//auth.IsUsingNativeUI = true;
viewController.PresentViewController((UIViewController)auth.GetUI(), true, null);
}
}

Related

Facebook complains that the app is not secure

When I try to login via Facebook, it throws the following error;
facebook has detected app isn't using a secure connection to transfer information
But I'm pretty sure that it is secured via 'Let's encrypt'.
I have checked Web and Client OAuth login boxes and set the corresponding redirect uris on developer facebook.
On maui side, I am calling the following code piece and AppSettings.BaseUrl is correct, I have checked that;
WebAuthenticatorResult authResult = await WebAuthenticator.Default.AuthenticateAsync(
new WebAuthenticatorOptions()
{
Url = new Uri($"{AppSettings.BaseUrl}account/authentication/{scheme}"),
CallbackUrl = new Uri("tibi://"),
PrefersEphemeralWebBrowserSession = true
});
And on backend side, the following api is requested;
[HttpGet("authentication/{scheme}")]
[AllowAnonymous]
public async Task Get([FromRoute] string scheme)
{
var auth = await Request.HttpContext.AuthenticateAsync(scheme);
if (!auth.Succeeded
|| auth?.Principal == null
|| !auth.Principal.Identities.Any(id => id.IsAuthenticated)
|| string.IsNullOrEmpty(auth.Properties.GetTokenValue("access_token")))
{
// Not authenticated, challenge
await Request.HttpContext.ChallengeAsync(scheme);
}
else
{
var claims = auth.Principal.Identities.FirstOrDefault()?.Claims;
var email = string.Empty;
email = claims?.FirstOrDefault(c => c.Type == System.Security.Claims.ClaimTypes.Email)?.Value;
// Get parameters to send back to the callback
var qs = new Dictionary<string, string>
{
{ "access_token", auth.Properties.GetTokenValue("access_token") },
{ "refresh_token", auth.Properties.GetTokenValue("refresh_token") ?? string.Empty },
{ "expires_in", (auth.Properties.ExpiresUtc?.ToUnixTimeSeconds() ?? -1).ToString() },
{ "email", email }
};
// Build the result url
var url = callbackScheme + "://#" + string.Join(
"&",
qs.Where(kvp => !string.IsNullOrEmpty(kvp.Value) && kvp.Value != "-1")
.Select(kvp => $"{WebUtility.UrlEncode(kvp.Key)}={WebUtility.UrlEncode(kvp.Value)}"));
// Redirect to final url
Request.Host = HostString.FromUriComponent(AppSettingsProvider.GatewayUrl);
Request.HttpContext.Response.Redirect(url);
}
}
Challenge is invoked successfully and redirects me to the Facebook login but when I sign in, I get the error above.

Web App Bot throws invalid status code 'Unauthorized' on Facebook Channel

I'm developing a Facebook with the Microsoft.Bot.Builder Framework (4.2.2)
The Bot Works on emulator and on Azure with the "Test in Web Chat" Really fine. But on the Facebook Channel I get an "There was an error sending this message to your bot: HTTP status code InternalServerError"
My log stream says:
019-04-12 13:23:22.154 +00:00 [Information]
Microsoft.AspNetCore.Hosting.Internal.WebHost: Request starting
HTTP/1.1 POST
http://thomasreigltestbot1995.azurewebsites.net/api/messages
application/json; charset=utf-8 688
2019-04-12 13:23:22.155 +00:00 [Information]
Microsoft.Bot.Builder.Integration.IAdapterIntegration: Received an
incoming activity. ActivityId: Vg2USjaJGCZ1Ib_-
LTftnL9F6qg_DCJaV3XbIqGzSpisuO10eYLezkjHJxSVcYAAUWQvynDJbUyfvyBgN30B3w
2019-04-12 13:23:22.155 +00:00 [Information]
Microsoft.Bot.Builder.Integration.IAdapterIntegration: Sending
activity. ReplyToId: Vg2USjaJGCZ1Ib_-
LTftnL9F6qg_DCJaV3XbIqGzSpisuO10eYLezkjHJxSVcYAAUWQvynDJbUyfvyBgN30B3w
2019-04-12 13:23:22.388 +00:00 [Error]
Facebook_Events_Bot.FacebookEventsBot: Exception caught :
Microsoft.Bot.Schema.ErrorResponseException: Operation returned an
invalid status code 'Unauthorized'at
Microsoft.Bot.Connector.Conversations.
This is my simple Bot from this repo:
https://github.com/Microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/23.facebook-events
public class FacebookEventsBot : IBot
{
private const string DialogId = "question";
/// </summary>
private readonly DialogSet _dialogs;
private Tuple<int, string> tuple;
public FacebookEventsBot(BotAccessors accessors)
{
if (accessors == null)
{
throw new ArgumentNullException(nameof(accessors));
}
_dialogs = new DialogSet(accessors.ConversationDialogState);
_dialogs.Add(new AttachmentPrompt(DialogId));
}
public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
{
const string facebookPageNameOption = "Facebook Page Name";
const string quickRepliesOption = "Quick Replies";
const string postBackOption = "PostBack";
if (turnContext == null)
{
throw new ArgumentNullException(nameof(turnContext));
}
// Check if we are on the Facebook channel.
if (turnContext.Activity.ChannelId == Channel.Channels.Facebook)
{
// Analyze Facebook payload from channel data.
ProcessFacebookPayload(turnContext.Activity.ChannelData);
// Initially the bot offers to showcase 3 Facebook features: Quick replies, PostBack and getting the Facebook Page Name.
// Below we also show how to get the messaging_optin payload separately as well.
switch (turnContext.Activity.Text)
{
// Here we showcase how to obtain the Facebook page name.
// This can be useful for the Facebook multi-page support provided by the Bot Framework.
// The Facebook page name from which the message comes from is in turnContext.Activity.Recipient.Name.
case facebookPageNameOption:
{
var reply = turnContext.Activity.CreateReply($"This message comes from the following Facebook Page: {turnContext.Activity.Recipient.Name}");
await turnContext.SendActivityAsync(reply);
break;
}
// Here we send a HeroCard with 2 options that will trigger a Facebook PostBack.
case postBackOption:
{
var dialogContext = await _dialogs.CreateContextAsync(turnContext, cancellationToken);
var results = await dialogContext.ContinueDialogAsync(cancellationToken);
var card = new HeroCard
{
Text = "Is 42 the answer to the ultimate question of Life, the Universe, and Everything?",
Buttons = new List<CardAction>
{
new CardAction() { Title = "Yes", Type = ActionTypes.PostBack, Value = "Yes" },
new CardAction() { Title = "No", Type = ActionTypes.PostBack, Value = "No" },
},
};
var reply = turnContext.Activity.CreateReply();
reply.Attachments = new List<Attachment> { card.ToAttachment() };
await turnContext.SendActivityAsync(reply);
break;
}
// By default we offer the users different actions that the bot supports, through quick replies.
case quickRepliesOption:
default:
{
var reply = turnContext.Activity.CreateReply("What Facebook feature would you like to try? Here are some quick replies to choose from!");
reply.SuggestedActions = new SuggestedActions()
{
Actions = new List<CardAction>()
{
new CardAction() { Title = quickRepliesOption, Type = ActionTypes.PostBack, Value = quickRepliesOption },
new CardAction() { Title = facebookPageNameOption, Type = ActionTypes.PostBack, Value = facebookPageNameOption },
new CardAction() { Title = postBackOption, Type = ActionTypes.PostBack, Value = postBackOption },
},
};
await turnContext.SendActivityAsync(reply);
break;
}
}
}
else
{
// Check if we are on the Facebook channel.
if (turnContext.Activity.ChannelId == Channel.Channels.Facebook)
{
// Here we can check for messaging_optin webhook event.
// Facebook Documentation for Message optin:
// https://developers.facebook.com/docs/messenger-platform/reference/webhook-events/messaging_optins/
}
await turnContext.SendActivityAsync($"Received activity of type {turnContext.Activity.Type}.");
}
}
private void ProcessFacebookPayload(object channelData)
{
// At this point we know we are on Facebook channel, and can consume the Facebook custom payload
// present in channelData.
var facebookPayload = (channelData as JObject)?.ToObject<FacebookPayload>();
if (facebookPayload != null)
{
// PostBack
if (facebookPayload.PostBack != null)
{
OnFacebookPostBack(facebookPayload.PostBack);
}
// Optin
else if (facebookPayload.Optin != null)
{
OnFacebookOptin(facebookPayload.Optin);
}
// Quick reply
else if (facebookPayload.Message?.QuickReply != null)
{
OnFacebookQuickReply(facebookPayload.Message.QuickReply);
}
// TODO: Handle other events that you're interested in...
}
}
private void OnFacebookOptin(FacebookOptin optin)
{
// TODO: Your optin event handling logic here...
}
private void OnFacebookPostBack(FacebookPostback postBack)
{
// TODO: Your PostBack handling logic here...
}
private void OnFacebookQuickReply(FacebookQuickReply quickReply)
{
// TODO: Your quick reply event handling logic here...
}
}
}

Can't get email or public profile facebook by ASP MVC5

I use MVC5 to get public profile user, but I just get ID and DisplayName of user. I have researched multi ways but have no result. This my setup snippet:
var options = new FacebookAuthenticationOptions
{
AppId = "xxx",
AppSecret = "xxx",
SignInAsAuthenticationType = "ExternalCookie",
Provider = new FacebookAuthenticationProvider
{
OnAuthenticated = async context =>
{
context.Identity.AddClaim(new System.Security.Claims.Claim("FacebookAccessToken", context.AccessToken));
}
}
};
options.Scope.Add("email");
options.Scope.Add("public_profile");
app.UseFacebookAuthentication(options);
And I call request result in action
public async Task<ActionResult> Index()
{
var userDisplayModel = new UserDisplayModel();
var authenticateResult = await AuthenticationManager.AuthenticateAsync("ExternalCookie");
if (authenticateResult != null)
{
userDisplayModel = new UserDisplayModel()
{
DisplayName = authenticateResult.Identity.Claims.FirstOrDefault(t => t.Type == ClaimTypes.Name).Value
};
}
return View(userDisplayModel);
}

picture upload on facebook

hi i am trying to upload images from my wp8.1 app to facebook but one of the issues is that pictures posted are visible to only me unless i amnually change it from facebook . i want to post them automatically for public to view . here is my code :
var postParams = new
{
access_token = ObjFBHelper.AccessToken,
message = "My message",
source = pic,
};
try
{
dynamic fbPostTaskResult = await fbclient.PostTaskAsync("me/photos",postParams);
var responseresult = (IDictionary<string, object>)fbPostTaskResult;
}
catch (Exception ex)
{
//MessageDialog ErrMsg = new MessageDialog("Error Ocuured!");
}
var parameters = new Dictionary<string, object>
{
{ "message", FacebookMessage },
{ "privacy", new Dictionary<string, object>
{
{ "value", "ALL_FRIENDS" }
}
}
};
I found this on stackoverflow. Maybe it helps you too?
From: SO question

iPhone cross-domain ajax request fails

Hi I am creating an application where I used ajax request to populate the List of Items.
It works in PC-Browser but not works in iPhone safari.
What could be the issue in safari? Please Help.
createXMLHTTPHandle:function(url,onSuccess,onError){
var xhttp;
try {
if(window.XMLHttpRequest) {
xhttp = new XMLHttpRequest();
} else {
xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xhttp.open("GET", url, false);
xhttp.setRequestHeader("Content-Type",
"text/xml;charset=utf-8");
xhttp.onreadystatechange = function() {
if(xhttp.readyState == 4) {
if(xhttp.status == 200)//clear db and parse
and store new data
{
onSuccess(xhttp.responseText);
}
}
};
xhttp.send();
}
catch(err) {//
if(err=="Error: NETWORK_ERR: XMLHttpRequest Exception 101")
alert("Please check your network connection!");
onError(err);
}
}