Xamarin android app throws object not set when calling api - android

So i have android app that makes several requests to api using following structure. Note that this works in iOS and this appeared to start happening after updating xamarin forms.
public async Task<Rootobject> GetData()
{
using (var httpClient = new HttpClient())
{
var response = await httpClient.GetAsync(url); //throws exception here. See screenshot
}
}
This works fine for all my requests except for one and the only difference is that this one is called from within a task factory like following:
tasks.Add(Task.Factory.StartNew(async()=>
{
var data = await GetData();
}));
And invoked like following:
Task.WhenAll(tasks).ContinueWith(t =>
{
IsBusy = false;
}).GetAwaiter();
The part that really has me confused is that this works as expected in iOS. Does anyone have any idea what i can do to get past this?

Turns out the api was not issue at all even though it seemed like it because that is where debugger would blow up but turned out issue was https://github.com/alexrainman/CarouselView/issues/557 and is still an issue. My work around is to use custom carousel view when android instead of plugin. Hope this helps someone not spend nearly two days on like i did.

Related

React Native Expo Android crashes only in production and is also not catchable in Sentry

Already tried to look into all different problems here on StackOverflow with related titles, like this one. But no success.
Here is the piece of code where the problem happens:
const fetchApi = useCallback(async () => {
setIsLoading(true);
if (activePortfolioId) {
try {
const response = await getApis().portfoliosApi.getPortfolioOverviewById(
activePortfolioId
);
if (response.data && response.data?.tickers?.length) {
setItems(handleListItems(response.data.tickers));
}
} catch (error) {
Sentry.Native.captureException(error);
Sentry.Native.captureMessage('HELLO?');
Alert.alert(
'Sorry!',
'We were unable to retrieve the performance list. Please try again later.'
);
} finally {
setIsLoading(false);
}
}
}, [activePortfolioId]);
So what happens is, on iOS I have no problem at all here, either on DEV or PROD, using real device or simulator, everything works fine, never went to the catch statement. On Android, using simulator or real device with Expo, it's all fine too, even using expo start --no-dev --minify to try to reproduce the app as PROD, occurs no errors at all. I have tried everything that came on my mind, like removing pieces of the code to see if the problem stops. Like instead of calling the API, just setting the items, like this:
setItems(handleListItems(response.data.tickers)); because I also thought that the problem might be with my handler function, I also tried to just do setItems([{ OBJECT HERE }]);. The problem has just stopped once I stopped setting the items. So I also tried to check my renderItem function, tried to stop using any styled component, just what React Native provides, nothing works. Then I decided to bring Sentry to my code but even with Sentry, no issues is shown there. I open the screen, it is loading, fetches the API, then it falls in the catch block, because I see the Alert on Android and then the app crashes and go back to the splash screen frozen. The only issue that appeared on Sentry was:
Could not open URL 'https://XXXXXXX': No Activity found to handle Intent { act=android.intent.action.VIEW dat=https://XXXXXXX... flg=0x10000000 }
But strangely I have never clicked on this during the "tests" and this link just appears on the login screen, shouldn't have anything to do with the problem itself, right?
I really don't know what else I could try to do and figure out what is causing this problem, so decided to ask for help and maybe find someone who already went through something similar.
Thanks!
PS: I'm using TS too, so apparently no problems with some possible undefined or whatever.
Found the issue, it was with the Intl. Solution here.

firebase.messaging().getInitialNotification() does not work on android(when app is killed)

So, I have migrated Firebase on my project from v#5 to v#14 because push-notifications did not work on android API31+(v12) at all.
NOTE: we use react-native-splash-screen. Folk pointed out on some problems react-native-firebase/issues/4005 and react-native-firebase/issues/2768 and react-native-splash-screen/issues/289 and suggested to move from older splash approach to react-native-bootsplash as an alternatiove, which was not really the solution for us.
PS. any comments inside links above did not help
firebase.messaging().onNotificationOpenedApp - Unlike initial pushes, in background mode push service was performing well as expected.
My problem was resolved by using API from 3d-party library such react-native-push-notification instead of firebase.messaging().getInitialNotification().
const getAndroidInitialNotification = (remoteMessage: ReceivedNotification | null): void => {
const data = remoteMessage?.data;
if (data) {
// Your code such deep links implementation, dispatch to reducer etc...
}
};
PushService.popInitialNotification(handleInitialNotifications);
Hope this will help for somebody like me, who do not understand what is the affection of splash approach on firebase service and all related confusing stuff.

How to trigger / debug backdoor functionality in Xamarin.Forms.UITesting?

I'm trying to add a BackdoorMethod to a Xamarin.Forms application to bypass the login (IDP - opened in chrome browser) step. I have the feeling that the method is not getting triggered, but not sure, and I don't know how could I make sure about it.
I've read the documentation here: https://learn.microsoft.com/en-us/appcenter/test-cloud/uitest/working-with-backdoors
Check this thread: https://forums.xamarin.com/discussion/85821/xamarin-uitest-backdoor-on-droid-with-splash-screen-how-do-i-access-my-mainactivity
Checked this example: https://github.com/brminnick/UITestSampleApp/tree/master/Src
In the MainActivity.cs file I've defined the BackdoorMethod:
[Preserve, Export(nameof(BypassLoginScreen))]
public string BypassLoginScreen()
{
// some additional code here. the code is working, when I called it
// directly from OnCreate it was executed without any error
return "called";
}
From the test case i'm trying to invoke it like:
public constructorMethod(Platform platform)
{
this.platform = platform;
app = AppInitializer.StartApp(platform);
var result = app.Invoke("BypassLoginScreen"); // result == "<VOID>"
}
I'm not getting any error message, the method simply not called, or not returns anything. (or i don't know what's happening there with it, because breakpoint also not working as the app started from the device)
This should be already working. I have similar code and it works for me.
you can add inside your function
Android.Util.Log.WriteLine(Android.Util.LogPriority.Info, "BypassLoginScreen", $"Some text as info");
And observe the result in Device Logs, Filter by BypassLoginScreen to see if there is any log created with the tag BypassLoginScreen

API call not working inside Anko Async

I'm trying to make an http request in Android, using Kotlin, and I've come across two ways of doing so.
One is the traditional way, using AsyncTask (not really pretty) which I got to work with the following code (just the doInBackground, as the rest of the class seemed unnecessary):
override fun doInBackground(vararg params: Void?): String? {
val url = URL("myUrl")
val httpClient = url.openConnection() as HttpURLConnection
if(httpClient.getResponseCode() == HttpURLConnection.HTTP_OK){
try {
val stream = BufferedInputStream(httpClient.getInputStream())
val data: String = readStream(inputStream = stream)
return data;
} catch (e : Exception) {
e.printStackTrace()
} finally {
httpClient.disconnect()
}
}else{
println("ERROR ${httpClient.getResponseCode()}")
}
return null
}
Now, I've come across a library called Anko, which many here know, and I tried to use its DSL for asynchronous tasks. The thing is, I haven't found a lot of info here about Anko for asynchronous tasks, so I thought I would open a new topic to see if someone could walk me through what I'm doing wrong, or what they think I should do to make it work.
The code I wanted to use is the following:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
async() {
val result = URL("myUrl").readText()
textView1.setText(result)
}
}
I tried to keep it as slim as possible so to minimize any potential mistakes, but I must be doing something wrong here because the code inside the async block is not doing anything, yet the app is not crashing and I'm not getting any exceptions. I've tried debugging it using Intellij IDEA, but after the first line inside the async block it stops the debugging while saying "The application is running". My best guess is that it got hung up somewhere in that first line due to the failed connection, but I don't know.
I've also tried to use the regular URL("myUrl").openConnection() inside the async block, but that hasn't worked either.
Anyway, any help would be deeply appreciated.
The problem textView1 contents not getting updated is caused by calling setText outside of main thread.
The documentation shows a nice example how to properly use async. Take a look at the following adapted version of your code:
async() {
val result = URL("http://stackoverflow.com/").readText()
uiThread {
textView1.text = result
}
}
PS. While not directly related to the question consider using a nicer http client i.e. Retrofit, OkHttp
The problem turned out to be a lot more basic than what I was thinking. It was a problem of compatibility apparently from having an older version of Android Studio running with the new version 1.0.2 of the Kotlin plugin and, again, apparently the function readText was not working properly and therefore I wasn't getting anything from it.
Anyway, I updated Android Studio, with the latest version of Kotlin and it started working fine, although I'm going to see if I can find out what it was that was causing the problem inside readText.

Unusual behaviour with changePage on android 2.3.6

I am building a phonegap app with jquery mobile and using build.phonegap.com
I have an event to change the page to the login screen after startup process have completed.
This works fine but it will not work on my andriod device unless a debugger is attached to it, in which case it works fine.
The code I have is
$.mobile.changePage("login.html");
I have put this in the mobileinit, pageshow, and now on document.ready function but it doesnt change the behaviour.
I've checked if $.mobile is a function and it is, Have tried everything and can not seem to figure out why this would be happening, any feedback would be much appreciated
I managed to put in a hack to work around this issue.
It was something to do with my phone being really old and slow, so something was getting a little messed up on old/slow andriod versions.
To prevent this from being an Issue I figured out this way that solves the issue and boots up my jquery mobile app on phone gap even if the phone is very slow.
$(document).bind('mobileinit', function () {
setTimeout(function () {
var html = $(".loading-status-text").html();
/* The html has Please Wait in the dom so we know it han't been touched by jQuery */
if (html == 'Please Wait') {
window.location.href = 'index.html';
}
}, 10000);
$(document).on("pageshow", function (e) {
var pageId = $.mobile.activePage.attr('id').toString();
if (pageId == 'loadingScreen') {
/* This wouldn't fire at first */
$(".loading-status-text").html("Welcome to Appname");
$.mobile.changePage("login.html");
}
});
});

Categories

Resources