Changing certificate for live application and purchases - xamarin.forms

I have a live app in the Xamarin UWP store and I have implemented the trial and a paid version which is working fine. Now I want to publish a new update of the app after I converted from PCL to.Net Standard 2.0. when I build, I get the certificate error and it asks me to enter the password for the certificate I uploaded to the server.
It doesn't accept my password. I am pretty sure that I enter a correct password. I don't know the reason. So my questions are;
Does certificate play any role in LicenseInformation? I am basically checking if it is trial or not with the code below. If I create a new certificate, will that cause any effect on existing purchases?
I tried with the new certificate using local CurrentAppSimulator, all works fine but although I re-associated to store app, I get exception using CurrentApp as below. Is it because of I am using different certificate than in the store? So if I provide a new submission with a new certificate, the problem will be solved?
System.ExceptionException from HRESULT: 0x803F6107 Raw at
Windows.ApplicationModel.Store.CurrentApp.get_LicenseInformation()
#if !DEBUG
licenseInformation = CurrentApp.LicenseInformation;
#else
licenseInformation = CurrentAppSimulator.LicenseInformation;
#endif
licenseInformation.LicenseChanged +=LicenseInformation_LicenseChanged;
if (licenseInformation.IsActive)
{
if (licenseInformation.IsTrial)
{

Now I want to publish a new update of the app after I converted from PCL to .Net Standard 2.0.
If you switch to the latest .NET Standard 2.0, you'd better use the Windows.Services.Store namespace relevant APIs instead. The Windows.ApplicationModel.Store Namespace document has explained clearly.
The Windows.ApplicationModel.Store namespace is no longer being updated with new features. If your project targets Windows 10 Anniversary Edition (10.0; Build 14393) or a later release in Visual Studio (that is, you are targeting Windows 10, version 1607, or later), we recommend that you use the Windows.Services.Store namespace instead. For more information, see In-app purchases and trials. The Windows.ApplicationModel.Store namespace is not supported in Windows desktop applications that use the Desktop Bridge or in apps or games that use a development sandbox in Dev Center (for example, this is the case for any game that integrates with Xbox Live). These products must use the Windows.Services.Store namespace to implement in-app purchases and trials.

Related

Do WinUI applications need runFullTrust to publish to the Windows Store?

I recently took a stock WinUI template, added my old UWP C# code, recompiled and tried to publish. The Windows Store Application Submission warns me that I shouldn't use the runFullTrust setting:
We detected the use of one or more restricted capabilities in your Package.appxmanifest file. You must request approval to use restricted capabilities by providing more information below. Please include as much detail as possible. Learn more
If you don't need to declare these capabilities or added them in error, you can remove them from your Package.appxmanifest file and then upload the updated package(s).
but here's what I got from the template:
<Capabilities>
<rescap:Capability Name="runFullTrust" />
</Capabilities>
I tried removing it, but it wouldn't even compile. Can anyone tell us the backstory of this flag, why it's needed in WinUI but not UWP, and how we get around the Windows Store Submission error.
Do WinUI applications need runFullTrust to publish to the Windows Store?
Yes.
A WinUI 3 app uses the full-trust desktop app model. A UWP app runs in a sandbox.
As stated in the docs, distributing your packaged desktop (WinUI 3) app requires you to answer "a few extra questions as part of the submission process. That's because your package manifest declares a restricted capability named runFullTrust, and we need to approve your application's use of that capability."
So you should provide information about why you need to use the runFullTrust restricted capability when you publish the app. You could for example explain that it's a desktop app and what it does.
WinUI 3 does not need to be full trust, but you still need to declare any UWP-like capacities you are using.
Here is a tutorial that shows how to do it.
https://nicksnettravels.builttoroam.com/winui-appcontainer/

Is there an alternative .NET logging class to ILogger / EventLog that runs on Mac?

I am injecting an object in a Blazor app as a singleton that is constructed using ILogger;
public MessageBroker(ILogger<MessageBroker> logger, IOptions<MessageBrokerConfig> config)
The app (.NET Core 5.0) crashes when I navigate to that page with;
Exception":"System.PlatformNotSupportedException: EventLog access is not supported on this platform.
I guess logging is one of the trickier functions to make cross platform because it is directly to the OS.
Does anyone know of an alternative to ILogger that will work on Mac Silicon, Windows, and Linux?
The problem is not in ILogger, but in its configuration. Apparently, it uses EventLog, which is used to write logs to Windows Event Log, not available on other platforms.
You most likely have something like that in your logging configuration.
logging.AddEventLog()
If you don't need to use Windows Event Log, just remove this line and use other logging providers instead. Console is the most basic one, just writes your logs in standard output.
If you are looking for more advanced scenarios, like logging to files or external log collectors, I can recommend Serilog or Log4Net, they should work on all platforms without an issue. You can find other alternatives in awesome-dotnet-core repo
If you really need to use Windows Event Log (e.g., your production server is Windows, but you develop on MacOS machine), you should probably wrap this line in an if statement and control it with configuration parameter
if (context.Configuration["UseEventLog"] == "true")
{
logging.AddEventLog()
}

SQLite no longer seems to work on xamarin android

We have a Xamarin.Forms project that needed to use the sqlite local db to store date. EF Core's sqlite library was used to set this up and by different developers from different PCs (vs 2019). Initially, it was used with the Database.EnsureCreated() function and later with ef core's migrations. All went smooth for more than a month.
Last week all of a sudden the android app wouldn't start on any one's PC due to some error with sqlite. It showed the following error:
Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR)
I spent a while trying all kinds of fixes and rollbacks thinking it was an issue with the code. This included the following:
Deleted obj and bin folders, cleaned and rebuilt for all below steps.
Downgraded the version of ef to 2.2.3 (the version we started with)
Rolled back to git commits up to a week back
Upgraded the versions of dependencies of ef core
Removed the past few migrations
Downgraded xamarin forms to 3.6.x
After trying the above and several other fixes, finally upgrading the versions of java and android SDK worked last Friday (on all PCs). Once this fix worked everything went smooth that day. On Tuesday once again the issue was back (no library updates or code changes). A deeper look at EF Cores logging shows that it crashes the moment it attempts to connect to a db.
The issue can be replicated on the android devices but not the emulators. I am not sure if there is some new permission in android we need to request for.
I finally created a new xamarin forms project with sqlite setup. I used the pcl library and ef core. I still found the same error.
Here is the git hub that replicates the issue https://github.com/neville-nazerane/xamarin-site
Update
Just something i noticed. eariler my database file was named "main.db". Now no matter what i change this file name to or no matter what variables i change. it always shows database name as "main" in logs. Not sure if changing the db name would fix the issue. However, never found a way to change this db name. I tried different connection strings, it just said "database" and "db" were unknown keys
Update
Steps to replicate:
using (var db = new AppDbContext())
{
db.Add(new Person {
Age = 55,
Name = "Neville"
});
db.SaveChanges();
Person[] alldata = db.People.ToArray();
}
The definitions of Person and AppDbContext are quite obvious. So, with the spirit of not making the question too long, I am not posting it here. However, if required I can post them too.
This is a bug with the Xamarin.Forms and Mono.
It was detected since a couple of months ago, it was fixed but then there was some regression (with VS 2019 v16.1).
Even with the latest release (v16.1.2) the bug still happens, so we need to wait for a fix.
Sources:
https://github.com/mono/mono/issues/14170
https://github.com/xamarin/xamarin-android/issues/3112
https://github.com/xamarin/xamarin-android/issues/2920
Due to slight differences of the particular file systems on the native side, I would suggest creating an interface to handle the actual database file handling on the native application level.
So here is how I implemented SQLite using the nuget package SQLite.Net-PCL:
In the shared project, create a new interface, for instance FileHandler.cs
public interface IFileHandler
{
SQLite.SQLiteConnection GetDbConnection();
}
You may want to extend that with more methods to save or retrieve various files, but for now we will just have the GetDbConnection Method to retrieve a working SQLite Connection.
Now in your Android implementation, we add the native implementation to that interface:
Create a new class called FileHandler.cs in your android project:
[assembly: Dependency(typeof(FileHandler))]
namespace YourProjectName.Droid
{
public class FileHandler : IFileHandler
{
public SQLite.SQLiteConnection GetDbConnection()
{
string sqliteFilename = "YourDbName.db3";
string path = Path.Combine(GetPersonalPath(), sqliteFilename);
SQLiteConnectionString connStr = new SQLiteConnectionString(path, true);
SQLiteConnectionWithLock connection = new SQLiteConnectionWithLock(connStr, SQLiteOpenFlags.Create | SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.NoMutex);
return connection;
}
private string GetPersonalPath()
{
return Environment.GetFolderPath(Environment.SpecialFolder.Personal);
}
}
}
Now back again in your shared code you can access that connection with the following code:
using (SQLiteConnection connection = DependencyService.Get<IFileHandler>().GetDbConnection())
{
// Do whatever you want to do with the database connection
}
Alright mate, I don't understand what issue you are facing. It might be an issue with your machine, I'd suggest using another computer/laptop.
I took the exact code that you shared on the Github. I was able to build it on my Mac computer in VS 2019 and installed the application in debug mode on my phone. I was able to add a date successfully, as you can see in the picture, and I placed an Exception Catchpoint and faced no exceptions.
I then proceeded to add another entry with the same details and it errored out with the message that you can see here
I would also suggest using Xamarin Profiler or any other Android logger to see the Stack Trace that you aren't able to see in your application output. It will give you details of the error, that you can share here for us to understand better.

SQLite Database Versioning and Xamarin Config String

I have an Xamarin Android (and maybe someday iOS) app that utilizes a rather sizable SQLite database (20MB+). I am somewhat new to mobile app development and definitely to Xamarin. I need to control database versioning. This is a best-practice question.
Edit/Clarification: Some of the data is app/user created or maintained. Some of the data is generated via a 3rd party and is read only, in 2nd and 3rd normal form. That data must be updated with version release. Also, the user will purchase some of these data sets in-app.
My Plan:
Everytime the app opens - OnStart (), I will validate the version of the database that is supposed to exist via a configuration string against a table value in the SQLite database with version info. If the versions don't match, the database file will be copied from the APK/assets to a local folder on the device, overwriting the existing file. I definitely don't want this to happen everytime the app opens for many reasons.
3-part question:
First, is this solution a solid approach without major road blocks? Where in Xamarin (or Android project) is best to store the database version string? And finally, is there a 3rd party library (preferably nuget) which already handles database versioning? I cannot find anything like that for .NET / Xamarin. Only some Java libraries which are more Android specific.

Google Drive API - Example code is not working

I want to use Google API to transfer SharePoint Documents to Google Drive using dot net. For that to happen I want to use this link Google Quick Start.
I have followed every little piece of information. It states in beginning "Complete the steps described in the rest of this page, and in about five minutes you'll have a simple Drive app that uploads a file to Google Drive" but it is not true.
I am trying to run this sample example since yesterday but failed.
// Register the authenticator and create the service
var provider = new NativeApplicationClient(GoogleAuthenticationServer.Description, CLIENT_ID, CLIENT_SECRET);
var auth = new OAuth2Authenticator<NativeApplicationClient>(provider, GetAuthorization);
So it seems that this code example is outdated and Google APIs have been upgraded.
Here comes the warning
[Obsolete("GoogleAuthenticationServer is not supported any more and it's going to be removed in 1.7.0-beta. Consider using the new Google.Apis.Auth NuGet package which supports .NET 4, .NET for Windows Store apps, Windows Phone 7.5 and 8 and Portable Class Libraries as well")]
Another code
var service = new DriveService(new BaseClientService.Initializer()
{
Authenticator = auth
});
And the error
Cannot implicitly convert type 'Google.Apis.Authentication.OAuth2.DotNetOpenAuth.NativeApplicationClient' to 'Google.Apis.Http.IConfigurableHttpClientInitializer'. An explicit conversion exists (are you missing a cast?)
Then I was looking for [latest release samples] there I found the source files.
I was not able able to run the sample also.
Here I was successfully authenticated but then had error for redirect Uri
My Client_Secrets.JSON looks like, as you can see I have set default redirect Uri to http://localhost/.
{"web":{"auth_uri":"https://accounts.google.com/o/oauth2/auth","client_secret":"secret","token_uri":"https://accounts.google.com/o/oauth2/token","client_email":email","redirect_uris":["http://localhost/"],"client_x509_cert_url":"aa#developer.gserviceaccount.com","client_id":"id","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","javascript_origins":["http://localhost:53404/"]}}
Now I can run this application but as mentioned getting error
Error: redirect_uri_mismatch
The redirect URI in the request: [[http://localhost:2430/authorize/]] did not match a registered redirect URI
I really don’t know from where this port number comes and from where this authorize comes. As you can see in my JSON, I have not set anything similar.
I am using VS 2010 SP1 Ultimate and Windows 7 home Basic.
I have tried to give complete information and my end goal is upload document in Google drive.
The tutorial you are following uses an older version of google.apis thats why you are seeing the not supported. Here are a couple of tutorials on how it works with the new version of the api.
http://daimto.com/google-oauth2-csharp/
http://daimto.com/google-drive-api-c/
Take a look in https://code.google.com/p/google-api-dotnet-client/source/browse/Tasks.ASP.NET.SimpleOAuth2/Default.aspx.cs?repo=samples. It's a Task API ASP.NET sample. As you can see you need to add several lines of code, but it works.
I downloaded the samples Eyal mentions and got that compiling before integrating with my own app. .Net needs to be 4 although it states it supports higher.
You have to set the redirect URI in the google developer console, not in your JSON. In your case, you would want to set it to http://localhost:2430/authorize/.

Resources