Xamarin Forms Location with Full features - xamarin.forms

Hi I am trying to build one Application in Xamarin forms which has huge dependency on location services.
Using Xamarin.Essentials I am able to get the location, but in Android its give the last known location and sometime its not that much accurate.
Problem 1.
But I am not able to add Location Listener so that once user change location, I can get notified.
Problem 2.
How to exactly know whether user has disabled Phone Location or App Location ?
Please guide me.. Thanks in advance

Problem #1
I don't know, but i think Xamarin.Essentials doesn't have Location Listener feature yet, might be wrong, but you can use this plugin from jamesmontemagno (also a main developer of Xamarin.Essentials), this plugin can track geolocation changes like this:
CrossGeolocator.Current.IsListening
Problem #2
Following the documentation here, you receive an exception for the following cases: permission was not granted or if the location is not enabled/supported
try
{
var location = await Geolocation.GetLastKnownLocationAsync();
if (location != null)
{
Console.WriteLine($"Latitude: {location.Latitude}, Longitude: {location.Longitude}, Altitude: {location.Altitude}");
}
}
catch (FeatureNotSupportedException fnsEx)
{
// Handle not supported on device exception
}
catch (FeatureNotEnabledException fneEx)
{
// Handle not enabled on device exception
}
catch (PermissionException pEx)
{
// Handle permission exception
}
catch (Exception ex)
{
// Unable to get location
}

Related

some codes don't work. i dont know why. how can i make the codes work?

I wanna make Login screen in unity. I'm gonna use firebase, and followed the manual in firebase page and some youtube channel to learn how to use firebase.
and.. some codes don't work. I used the codes that firebase give, and the codes that are below login success don't work. um.. sorry for my weak English. please see the codes. thanks.
this codes don't work
authUI.ShowLoggedInPanel();// 로그인 성공 시 메인메뉴로 전환!
authUI.LoggedInUserEmail.text = newUser.Email;
I don't know what i can try..
private void TryLoginWithFirebaseAuth(string email, string password) // 기존 사용자 로그인
{
auth.SignInWithEmailAndPasswordAsync(email, password).ContinueWith(task =>
{
if (task.IsCanceled)
{
Debug.LogError("SignInWithEmailAndPasswordAsync was canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError("SignInWithEmailAndPasswordAsync encountered an error: " + task.Exception);
return;
}
// 로그인 성공 (Maybe Login success?)
Firebase.Auth.FirebaseUser newUser = task.Result;
Debug.LogFormat("User signed in successfully: {0} ({1})",
newUser.DisplayName, newUser.UserId);
authUI.ShowLoggedInPanel();// 로그인 성공 시 메인메뉴로 전환!
authUI.LoggedInUserEmail.text = newUser.Email;
});
}
It doesn't show the error to me. but just.. it doesn't work.
Could someone help me out here.
I don't know Firebase well but the issue might be the threading.
All (the most) Unity API calls have to be done in the main thread. Since Firebase executes its stuff async in a background thread some calls might simply fail.
You should rather use an Action parameter in order to pass a callback to the method like e.g.
private void TryLoginWithFirebaseAuth(string email, string password, Action<Firebase.Auth.FirebaseUser> successCallback) // 기존 사용자 로그인
{
auth.SignInWithEmailAndPasswordAsync(email, password).ContinueWith(task =>
{
if (task.IsCanceled)
{
Debug.LogError("SignInWithEmailAndPasswordAsync was canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError("SignInWithEmailAndPasswordAsync encountered an error: " + task.Exception);
return;
}
// 로그인 성공 (Maybe Login success?)
Firebase.Auth.FirebaseUser newUser = task.Result;
successCallback?Invoke(newUser);
});
}
and use it like
TryLoginWithFirebaseAuth(someName, somePassword, onSuccess =>
{
Debug.LogFormat("User signed in successfully: {0} ({1})",
onSuccess.DisplayName, onSuccess.UserId);
authUI.ShowLoggedInPanel();// 로그인 성공 시 메인메뉴로 전환!
authUI.LoggedInUserEmail.text = onSuccess.Email;
}
this makes sure it is definitely executed in the Unity main thread.
It's hard to definitely answer your question without more context around it (ex: are there any useful logs in the Unity console?).
Some things to note:
You have to make sure you've setup Authentication in the Firebase Console. This means clicking Authentication in your side bar and explicitly enabling the methods you want:
Similarly, you need to make sure that your applications are properly setup. Your package id/bundle id (Android/iOS) need to match what's in your console. Similarly, you need to upload the SHA1 of your signing certificate to get it to work in Android.
I'm assuming that you're just debugging for now, so you can get your debug certificate here: https://developers.google.com/android/guides/client-auth
You'll want to open up project settings:
And add your fingerprint there:
Following up on #derHugo's suggest, threading may be an issue in addition to the basic setup instructions above. I wrote a post recently on how to work with threading and Firebase in Unity here: https://firebase.googleblog.com/2019/07/firebase-and-tasks-how-to-deal-with.html
The easiest way to make your code thread safe would be to replace ContinueWith with ContinueWithOnMainThread. This is an extension method on Task provided by the Firebase plugin to make it easier to work with.
I hope that all helps!
This is a classic Task continuation problem in Unity using Firebase. When you use, ContinueWith it is not ensured to be called on the main Unity thread. What you're trying to do authUI.ShowLoggedInPanel();authUI.LoggedInUserEmail.text = newUser.Email; requires to be executed on the Unity main thread. If you try to access GameObjects inside ContinueWith, that will fail. The code just ghosts out without any error in the console.
The solution:
Instead of ContinueWith, use ContinueWithOnMainThread from Firebase extensions which was made exactly for this reason.

Issue with jwt-bearer on-behalf-of grant in Azure AD

So I have an Angular app that uses the adal-angular library to authenticate with an ASP.NET Core 2.0 Web API. The API then uses on-behalf-of flow to authenticate with another API using the users token like this MS article https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-on-behalf-of.
The issue I have is this is working fine in the DEV environment but I have now deployed a TST environment with separate App Registrations and I am receiving the following exception when I try and request the token using on-behalf-of
AADSTS240002: Input id_token cannot be used as 'urn:ietf:params:oauth:grant-type:jwt-bearer' grant.
The code I am using to request the token
public async Task<string> AcquireTokenAsync(string resource)
{
try
{
string accessToken = await _httpContextAccessor.HttpContext.GetTokenAsync(AuthenticationConstants.AccessToken);
var credentials = new ClientCredential(_azureOptions.ClientId, _azureOptions.ClientSecret);
var authContext = new AuthenticationContext($"{_azureOptions.Instance}{_azureOptions.TenantId}")
{
ExtendedLifeTimeEnabled = true
};
// On-behalf-of auth token request call
var authResult = await authContext.AcquireTokenAsync(
resource,
credentials,
new UserAssertion(accessToken));
return authResult.AccessToken;
}
catch (AdalServiceException asex)
{
_logger.LogError(asex, $"Instance: {_azureOptions.Instance} Tenant: {_azureOptions.TenantId} ClientId: {_azureOptions.ClientId}");
throw;
}
catch (System.Exception ex)
{
_logger.LogError(ex, ex.Message);
throw;
}
}
And I have used Fiddler and it looks like all the correct parameters are being passed.
Any help would be very much appreciated. I have set knownClientApplications on the second API and I have granted permissions on the Angular backend API to the second API.
For me, I got it to work by changing BOTH of the following to true:
oauth2AllowImplicitFlow
oauth2AllowIdTokenImplicitFlow
See here for more information.
According to your question and the error, it should be caused by that you angular app is not a Native(public) app.
For using this OBO flow with this Grant type, your client must be a public client not credential client.
If you want to register your client as a WebApp/API, you can refer to this Implementation:
Hope this helps!
Update
According to OP's comment, he/she got it working by changing oauth2AllowImplicitFlow from false to true.
We had this problem last week with one Azure Service Registration and not another. A review found that the token didn't return an AIO being returned. It turns out that the registration had redirects with wildcards (e.g., https://*.ngrok.io) and this is incompatible with the AcquireTokenOnBehalfOf function. I'm posting this here so a future person, probably me, will find it.
I was having problems even when oauth2AllowImplicitFlow and oauth2AllowIdTokenImplicitFlow were set to true. One of my Reply URLs had a wildcard in it. When the wildcard was removed, the issue was resolved.

Can't get user information after login successfully in WSO2 Identity server

After login successfully into WSO IS with service URL (https://localhost:9443/services/")
I tried to get User Information as below :
try {
UserRealm realm = WSRealmBuilder.createWSRealm(serviceURL, authCookie, configCtx);
UserStoreManager storeManager = realm.getUserStoreManager();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
But I had exception relating to this as below image. I can't get any info.
I tried and found out that the main error is I can't create ConfixContext with the following code :
configCtx = ConfigurationContextFactory.createConfigurationContextFromFileSystem(null, null);
I also read about ConfigContext in the below link and tried with other methods in this link but I can't create configContext.
http://axis.apache.org/axis2/java/core/apidocs/org/apache/axis2/context/ConfigurationContextFactory.html
I appreciate your help in this case.
Thanks
The problem is your runtime doesnt have org.wso2.carbon.user.api.UserStoreException class. Therefore you can't identify the real exception.
For now, just use Exception e instead, and see if you can log the real exception.

How to Programatically Check if the Location Services is Turned On or Off in browser using asp.net

i'm developing a website that use geolocation, but nothing happens if i access it with location service disabled. It should show user alert message to enable location service.
What you can do, if geolocation is supported by browser, is check the error code of getCurrentPosition
PERMISSION_DENIED - if the user clicks that “Don’t Share” button or otherwise denies you access to their location.
POSITION_UNAVAILABLE - if the network is down or the positioning satellites can’t be contacted.
TIMEOUT - if the network is up but it takes too long to calculate the user’s position. How long is “too long”? I’ll show you how to
define that in the next section.
if(navigator.geolocation){
navigator.geolocation.getCurrentPosition(
docode, handle_error)
}
function handle_error(err) {
if (err.code == 1) {
// PERMISSION_DENIED
}
else if (err.code == 2) {
// POSITION_UNAVAILABLE
}
else if (err.code == 3) {
// TIMEOUT
}
}

Getting App_Start Code First Migrations to work with Miniprofiler

I am running code first migrations. (EF 4.3.1)
I am also running Miniprofiler.
I run my code first migrations through code on App_Start.
My code looks like this:
public static int IsMigrating = 0;
private static void UpdateDatabase()
{
try
{
if (0 == System.Threading.Interlocked.Exchange(ref IsMigrating, 1))
{
try
{
// Automatically migrate database to catch up.
Elmah.ErrorLog.GetDefault(null).Log(new Elmah.Error(new Exception("Checking db for pending migrations.")));
var dbMigrator = new DbMigrator(new Ninja.Data.Migrations.Configuration());
var pendingMigrations = string.Join(", ", dbMigrator.GetPendingMigrations().ToArray());
Elmah.ErrorLog.GetDefault(null).Log(new Elmah.Error(new Exception("The database needs these code updates: " + pendingMigrations)));
dbMigrator.Update();
Elmah.ErrorLog.GetDefault(null).Log(new Elmah.Error(new Exception("Done upgrading database.")));
}
finally
{
System.Threading.Interlocked.Exchange(ref IsMigrating, 0);
}
}
}
catch (System.Data.Entity.Migrations.Infrastructure.AutomaticDataLossException ex)
{
Elmah.ErrorLog.GetDefault(null).Log(new Elmah.Error(ex));
}
catch (Exception ex)
{
Elmah.ErrorLog.GetDefault(null).Log(new Elmah.Error(ex));
}
}
The problem is that my DbUpdate is about to get called and then my app throws an exception which I think comes from the app on the first web page request.
saying:
Unable to update database to match the current model because there are pending changes and automatic migration is disabled. Either write the pending model changes to a code-based migration or enable automatic migration. Set DbMigrationsConfiguration.AutomaticMigrationsEnabled to true to enable automatic migration.
The problem is that I think my homepage is firing the dbcontext and this error before my dbupdate has finished.
How would you go about solving this?
Should I make the context wait using locks etc or is there an easier way?
More interestingly, If i start and stop the app a few times the db changes are pushed and the error goes away...
So I need to find a way to have the first request to the database on App_Start wait for the migrations to happen.
Thoughts?

Resources