Seems this API is broken and/or abandoned because in some days, this API call always fails during a few hours. Today is happening again, but it's taking more time than previous times.
I don't know what to do. I have 2 Air apps and they aren't working today.
Any solution on this?
Here is a simple piece of code:
FacebookMobile.init(APP_ID, onInit);
private function onInit(fbSession:Object, fail:Object):void
{
if (fbSession){
trace(fbSession.accessToken);
}
else{
traceV2(fail); // it's a "deep" trace
// other API methods related to login
}
}
In FacebookMobile.init(), we have to expect for an session object (containing FB acess token), or a "fail" object.
The fail object is returning this to me:
[Object]
| [error:Object]
| code = 190
| message = Malformed access token AAAEWSUA8XjUBAJo4JuO5hUMwSnKC95LNRr1nHHIU8rwPGzxvHIuhUcDziZA9ZC3xDf4ZBwYcqjVU1ir5wf5jlEsJ5zwyMhnnWGyWxXeKQZDZD,AAAEWSUA8XjUBAJo4JuO5hUMwSnKC95LNRr1nHHIU8rwPGzxvHIuhUcDziZA9ZC3xDf4ZBwYcqjVU1ir5wf5jlEsJ5zwyMhnnWGyWxXeKQZDZD
| type = OAuthException
Thanks in advance!
Problem fixed.
The solution to this specific problem is at at com.facebook.graph.FacebookMobile:560, inside the handleLogin() function.
protected function handleLogin(result:Object, fail:Object):void {
loginWindow.loginCallback = null;
if (fail) {
loginCallback(null, fail);
return;
}
// ---------------||--------------------//
// ---------------\/--------------------//
// This line below solves this problem
result.access_token = String(result.access_token).split(',')[0];
// ---------------/\-------------------//
// ---------------||-------------------//
session = new FacebookSession();
session.accessToken = result.access_token;
session.expireDate = (result.expires_in == 0) ? null : FacebookDataUtils.stringToDate(result.expires_in) ;
if (_manageSession) {
var so:SharedObject = SharedObject.getLocal(SO_NAME);
so.data.accessToken = session.accessToken;
so.data.expireDate = session.expireDate;
so.flush();
}
verifyAccessToken();
}
Seems like its a bug with Facebook returning the Access token as an Array:
http://developers.facebook.com/bugs/276418065796236?browse=search_5034a345a2cb15e92344737
I would try edit the String that is returned by removing the second access token value in it. (Everything after the comma) and signing that to your local sessions access token variable. It might resolve the issue
Related
I have a Flex app that connects to a JBoss/MS-SQL back-end. Some of our customers have a proxy server in front of their JBoss with a timeout of 90 seconds. In our application there are searches that can take up to 2-3 minutes for complex criteria. Since the proxy isn't smart enough to recognize AMF's keep alive pings for what they are the proxy sends a 503 to the client, which in Flex land becomes a "Channel Call Failed" event. In searching SO and other places, this seems to be a common problem. We can't do anything about the proxy or lengthen the timeout, the application needs to handle it.
Of course the back-end continues to process and eventually ships the results to the client. But the user gets an ugly error message and assumes the app is broke.
The solution I have settled on is to consume the CCF error and have the client continue to wait. I have managed the first part, but I can't figure out how to keep the client's handlers active to receive the data (and/or consume another timeout if necessary).
Current error handler:
private function handleSearchError(event : FaultEvent) : void {
if (event.fault.faultCode == "Channel.Call.Failed") {
event.stopImmediatePropagation(); // doesn't seem to help
return;
}
if (searchProgress != null) {
PopUpManager.removePopUp(searchProgress);
searchProgress = null;
}
etc...
}
This is the setup:
<mx:Button id="btnSearch" label="
{resourceManager.getString('recon_perspective',
'ReconPerspective.ReconView.search')}" icon="{iconSearch}"
click="handleSearch()" includeIn="search, default"/>
And:
<mx:method name="search" result="event.token.resultHandler(event);"
fault="handleSearchError(event);"/>
Kicking off the call:
var token : AsyncToken = null;
token = sMSrv.search(searchType.toString(), getSearchMode(), criteria,
smartMatchParent.isArchiveMode);
searchProgress = LoadProgress(PopUpManager.createPopUp
(FlexGlobals.topLevelApplication as DisplayObject, LoadProgress, true));
searchProgress.title = resourceManager.getString('matching', 'smartmatch.loading.trans');
searchProgress.token = token;
searchProgress.showCancelButton = true;
PopUpManager.centerPopUp(searchProgress);
token.resultHandler = handleSearchResults;
token.cancelSearch = false;
So my question is how do I keep handleSearch and handleSearchError alive to consume the events from the server?
I verified that the data comes back from the server using WebDeveloper in the browser to watch the network traffic and if you cause the app to refresh that screen, the data gets displayed.
I'm very in experienced but would this help?
private function handleSearchError(event : FaultEvent) : void {
if (event.fault.faultCode == "Channel.Call.Failed") {
event.stopImmediatePropagation(); // doesn't seem to help
if(event.isImmediatePropagationStopped(true)) {
//After stopped do something here?
}
return;
}
if (searchProgress != null) {
PopUpManager.removePopUp(searchProgress);
searchProgress = null;
}
etc...
}
m having an issue with Office 365 EWS (its only Office 365, Exchange 2010 and 2013 work fine). I can create my pull subscription without error but when I go to use it by calling
getEvents()
I receive an error:
ErrorNoRespondingCASInDestinationSite
The following error occured while retrieving events for exchange
resource: - Exchange Web Services are not currently
available for this request because none of the Client Access Servers
in the destination site could process the request.
Here is some code snippets
Using autodiscover and setting up credentials
this.exchangeService.Credentials = new NetworkCredential(this.Username, this.Password);
try {
this.exchangeService.AutodiscoverUrl(this.Username, RedirectionCallback);
}
catch(Exception ex)
{
Logger.WriteToEventLog(EventLogEntryType.Warning, 104, "ExchangeDataAccess, AutodiscoverURL error: " + ex.Message);
}
if (exchangeService.Url == null)
{
this.ExchangeServerURL = GetOffice365EWSUrl(this.Username);
this.exchangeService.Url = new Uri(this.ExchangeServerURL);
this.exchangeService.CookieContainer = new CookieContainer();
}
Afterwhich we Login and find our exchange user that we will perform all operations under
ServicePointManager.ServerCertificateValidationCallback = (sender1, certificate, chain, errors) => true;
string username = this.Username;
if (this.authenticateContext.GetExchangeServerVersion().Contains("365"))
{
username = this.Username.Remove(this.Username.IndexOf("#"));
}
NameResolutionCollection resolveNameResult = this.exchangeService.ResolveName(username, ResolveNameSearchLocation.ContactsThenDirectory, true);
if (resolveNameResult.Count() > 0)
{
roomEmailAddress = resolveNameResult[0].Mailbox.Address;
if (!string.IsNullOrEmpty(roomEmailAddress))
{
this.ExchangeUserEmailAddress = roomEmailAddress;
logMsg.AppendLine("Logged into Exchange with " + roomEmailAddress + " successfully, RetrieveRoomsList is next");
}
}
We then get a SubscribeResponse and save it to a list
subscribeResponse = this.exchangeDataAccess.ExchangeSubscribe(syncPoint.ThirdPartyId, syncPoint.Watermark, true);
We pass the above object into a wrapper method to get all Events from the EWS
Dictionary<PullSubscription, IEnumerable<ItemEvent>> mailboxEvents = null;
GetEventsResults eventsResults = subscription.GetEvents();
if (eventsResults == null || eventsResults.ItemEvents.Count() == 0) {
return mailboxEvents;
}
mailboxEvents = new Dictionary<PullSubscription, IEnumerable<ItemEvent>>();
mailboxEvents.Add(subscription, eventsResults.ItemEvents);
return mailboxEvents;
The line that calls subscription.GetEvents() is where the exception indicated at the top is returned.
There is another layer of complexity added on because our Exchange user has a domain name of #FOOlab.onmicrosoft.com where as all of the rooms being managed have a domain name of #LAB.FOO.COM
According to the customer this is ADFS authentication, however I really don't know much about it.
I can say however that this code base did work (got events) and then something seemed to change and the error started popping up. Originally I thought the customer changed something but we have tested this against another Office 365 (without ADFS) and saw the same error, so now I don't know what to think.
The links below can explain it far better then I can, but what I have done so far which has resolved my issue is to surround the GetEvents
with the add and removal of the header data X-AnchorMailbox
MSDN Link1 Link2
public Dictionary<PullSubscription, IEnumerable<ItemEvent>> GetEvents(SyncPoint syncpoint)
{
Dictionary<PullSubscription, IEnumerable<ItemEvent>> mailboxEvents = null;
if (this.authenticateContext.GetExchangeServerVersion().Contains("365"))
{
try
{
//this is to maintain affinity (see here https://msdn.microsoft.com/en-us/library/office/dn458789(v=exchg.150).aspx)
//it was added to fix an error: The following error occured while retrieving events for exchange resource: <room address> - Exchange Web Services are not currently available for this request because none of the Client Access Servers in the destination site could process the request.
//according to docs it is only when getting notifications that its important
if (this.exchangeService.HttpHeaders.Any(m => m.Key.Equals("X-AnchorMailbox")))
{
this.exchangeService.HttpHeaders.Remove("X-AnchorMailbox");
}
this.exchangeService.HttpHeaders.Add("X-AnchorMailbox", syncpoint.ThirdPartyId); //this is the email address of the mailbox being queried
}
catch { }
}
GetEventsResults eventsResults = syncpoint.pullSubscription.GetEvents();
if (eventsResults == null || eventsResults.ItemEvents.Count() == 0)
{
return mailboxEvents;
}
mailboxEvents = new Dictionary<PullSubscription, IEnumerable<ItemEvent>>();
mailboxEvents.Add(syncpoint.pullSubscription, eventsResults.ItemEvents);
try
{
this.exchangeService.HttpHeaders.Remove("X-AnchorMailbox");
} catch { }
return mailboxEvents;
}
I have an array = [ 'something', 'other' ]
And I want to retrieve only the values of those 2 ids from Firebase, which contains more than 2 items ( potentially millions ), but if I do this:
var questionRef = new Firebase(fireBaseURL+"/morethanamillionitems/");
loadUID.once('value', function (dataSnapshot) {
dataSnapshot.forEach(function(childSnapshot) { // Firebase method
console.log(dataSnapshot.numChildren()); // potentially outputs 1.000.000 +
var uid = childSnapshot.name();
var childData = childSnapshot.val();
console.log(uid.indexOf('something'));
result.push(uid)
});
}
I first basically load the whole database, which is not that efficient
Now I could do:
array.forEach(key, function() {
var questionRef = new Firebase(fireBaseURL+"/morethanamillionitems/"+key);
refID = questionRef.val();
result.push(refID);
})
Or maybe:
questionRef = new Firebase(fireBaseURL+"/morethanamillionitems/");
array.forEach(key, function() {
if ( questionRef.child(key) !== null ){
refID = questionRef.val();
result.push(refID);
}
})
The last one seems the nicest, the previous one seems a bit expensive on the old RAM.
However, I apparently have to call questionRef.once('value', function(){}) each time, hence already loading the whole document-root...
Or am I misunderstanding how Firebase handles these requests? is the .numChildren() just an answer directly from the server?
Is the .forEach actually remotely executed?
I'm wondering if there is any other way to reduce traffic per request. Which brings me to another question: it seems that firebase searches locally first, but eventually will search remotely, but it's not clear when this exactly happens. Does it periodically check if something has changed? Or will that only happend when I use .on() and not .once().
Or am I using the wrong backend for this purpose? Any other suggestions? I tried hood.ie which is still very beta, looked at Parse but firebase seemed to have the simplicity I need.
(sorry for the sloppy syntax, but you can see what I intended)
[update]
I now have this:
load: function(uids){
var FB = new Firebase(URL);
uids.map(function(uid) {
var currentRef = FB.child( uid+"/_current" );
currentRef.once('value', function (each) {
eachVal = each.val()
if (eachVal !== null){
var localSave = {};
localSave[uid] = eachVal;
this.saveLocal(localSave)
} else {
console.error("Not found: [%s]", uid)
}}, function (err) { });
});
}
But I'm still wondering when the request actually happens, on .child()? or in .once() and if the latter, what is the use of .child() exactly? It seems it's only used for referencing.
Then the second thing, if I want to retrieve an array of a hundred items, this would still mean a hundred seperate requests? or does Firebase have a way of collecting requests and then send them in a batch?
In that last case .once would be a more 'conservative' option for initial retrieval, then later you could attach a .on listener if you need real-time updates.
I'm having trouble accessing a text file that is packaged with my Windows Phone 8 app.
Here is the code:
var ResrouceStream = Application.GetResourceStream(new Uri("Data-Test.docx", UriKind.Relative));
if (ResrouceStream != null)
{
Stream myFileStream = ResrouceStream.Stream;
if (myFileStream.CanRead)
{
// logiic here
retrun "Hi";
}
}
else
{
return "hello";
}
Seems simple but the app always returns "hello". i have placed the file in root and also in assets, changed it to content - copy and do not copy, resource copy and do not copy but always it returns "hello".
Spent several hours on this and all solutions I can find show the solution or very similar above!
What am I doing wrong?
EDIT: Returns "hello" when I deploy to phone or emulator.
also tried "/Data-Test...", #"\Data-Text..., #/"Data-Test...!
UPDATE 1:
string aReturn = "";
var asm = Assembly.GetExecutingAssembly();
//Use this to verify the namespacing of the "Embedded Resource".
//asm.GetManifestResourceNames()
// .ToList()
// .ForEach(name => Debug.WriteLine(name));
var ResourceStream = asm.GetManifestResourceStream("ContosoSocial.Assets.QuizQuestions.QuizQuestions-Test1.docx");
if (ResourceStream != null) // <--CHECKED AND DOES NOT EQUAL NULL
{
Stream myFileStream = ResourceStream;
if (myFileStream.CanRead) // <-- CHEACKED AND CAN READ
{
StreamReader myStreamReader = new StreamReader(myFileStream);
LOGIC & EXCEPTION HERE...?
string myLine = myStreamReader.ReadLine();
}
else
{
aReturn = "myFileStream.CanRead = true";
}
}
else
{
aReturn = "stream equals null";
}
Debug.WriteLine(aReturn);
}
The assignment of myFileStream to a StreamReader object is throwing the exception null pointer. I thought I would wrap myFileStream to a StreamReader so I can read a line at a time..? This is my first c# project and I'm unfamiliar with it's syntax and classes.
UPDATE 2:
OK I added...
Debug.WriteLine(aReturn);
...following...
string myLine = myStreamReader.ReadLine();
...and noticed it was retrieving only the 2 characters 'PK' !
So saved the .docx file as .txt and reinserted adn changed build copy to embedded - do not copy...Happy days it now pulls off the first line in the file.
Thanks to OmegaMan for your help with this one :-)
Change file type in the project to Embedded Resource
Extract the resource by working the namespace to its location. Here is an example code where I pull in an XSD:
Code:
var asm = Assembly.GetExecutingAssembly();
// Use this to verify the namespacing of the "Embedded Resource".
// asm.GetManifestResourceNames()
// .ToList()
// .ForEach(name => Debug.WriteLine(name));
var f1 = asm.GetManifestResourceStream("UnitTests.Resources.NexusResponse.xsd");
Note this is not tested on WP8, but GetExecutingAssembly is stated to work within .Net. If you get the namespace wrong, uncomment out the code and display or debug to determine the resources and their namespace.
The following code displays a proper list of available chromecast devices on my network. But when I click on the links, the application never launches. There are a couple of things that I'm quite confused about that may or may not be related to this question:
If I'm making my own custom application, what's with the DIAL parameters and why do I have to pass them? I don't want to write an app for the DIAL standard... this is MY app.
Again related to the DIAL parameters, if I search for devices with any other query other than "YouTube" (a DIAL parameter), the list always comes up blank. I suppose I shouldn't care, as long as the device is listed... but again... the app won't launch.
It should be noted that my sender app is a chrome webpage.
I'm a bit confused as to where my "appid" goes int he launch parameters,'
<html data-cast-api-enabled="true">
<body>
hi!<BR/>
<script>
var cast_api, cv_activity;
if (window.cast && window.cast.isAvailable) {
// Cast is known to be available
initializeApi();
} else {
// Wait for API to post a message to us
window.addEventListener("message", function(event) {
if (event.source == window && event.data &&
event.data.source == "CastApi" &&
event.data.event == "Hello")
{
//document.write("Initialize via message.<br/>");
initializeApi();
//document.write("Api initialized via message.");
};
});
};
initializeApi = function() {
cast_api = new cast.Api();
cast_api.addReceiverListener("YouTube", onReceiverList);
};
var g_list;
onReceiverList = function(list) {
g_list = list;
// If the list is non-empty, show a widget with
// the friendly names of receivers.
// When a receiver is picked, invoke doLaunch with the receiver.
document.write("Receivers: "+list.length+"<br/>");
var t;
for(t=0;t<list.length;t++)
document.write('found:'+list[t].name+' ' +list[t].id+'<br/>');
};
onLaunch = function(activity) {
if (activity.status == "running") {
cv_activity = activity;
// update UI to reflect that the receiver has received the
// launch command and should start video playback.
} else if (activity.status == "error") {
cv_activity = null;
}
};
function launchy(idx)
{
doLaunch(g_list[idx]);
}
doLaunch = function(receiver) {
var request = new window.cast.LaunchRequest(">>>>>what REALLY goes here?<<<<<<< ", receiver);
request.parameters = "v=abcdefg";
request.description = new window.cast.LaunchDescription();
request.description.text = "My Cat Video";
request.description.url = "http://my.website.get.your.own/chomecast/test.php";
cast_api.launch(request, onLaunch);
};
stopPlayback = function() {
if (cv_activity) {
cast_api.stopActivity(cv_activity.activityId);
}
};
</script>
</body>
</html>
The part marked "what really goes here?" is the part that I THINK is wrong... I couldn't be completely wrong. My device is white listed, I have an appid (which I thought might go in that slot)... The documentation merely says ActivityType DIAL Parmeters are valid, mandatory.
The first argument to the LaunchRequest is your App ID, the one that you have received in an email as part of whitelisting process. Also, the "YouTube" in the initialize method should also be replaced with the same App ID.
I strongly suggest you look at the sample that is on GitHub for chrome sender to see how you can send a request to load a media on a cast device.