0

I've been trying to add a backup/restore option to my app, so I searched and found some useful info (that seemed easy to do).

One of them being about the File from Xamarin.Essentials, which I tried to use, but keeps giving me an "access denied" error.

Getting the db directory:

public Restaurar()
  {
     InitializeComponent();
     localPath = Path.Combine(FileSystem.AppDataDirectory, templateFileName);
  }

The original file and the backup names and also the localpath:

const string templateFileName = "database.sqlite";

const string localFileName = "backup_database.sqlite";

string localPath;

The function to create a backup:

private void BtnBackup_Clicked(object sender, EventArgs e)
  {
      var reading = File.ReadAllText(localPath);
      File.WriteAllText(localFileName, reading);
      DisplayAlert("BACKUP", "Backup file created!", "OK");
  }

Moving the backup file to the specific database folder:

private void BtnMove_Clicked(object sender, EventArgs e)
  {
     File.Move(localFileName, FileSystem.AppDataDirectory);
  }

I got the following exception when clicking the Backup button:

System.UnauthorizedAccessException: 'Access to the path "/backup_database.sqlite" is denied.'

And clicking the Move button:

System.IO.FileNotFoundException: 'Could not find file'/backup_database.sqlite'.' 

I thought that would create a new file on the project folder which I would be able to move the android/IOS database folder. I appreciate any help, thanks in advance!

EDIT:

I tried a different approach:

I already have a DependecyService to get the platform specific path to the database, so I used it.

Backup:

    private void BtnBackup_Clicked(object sender, EventArgs e)
    {
        var dep = DependencyService.Get<IPath>();
        string db_path = dep.GetPath("database.sqlite");
        string backup_path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData));

        var origin = File.ReadAllBytes(db_path);
        File.WriteAllBytes(backup_path, origin);

        DisplayAlert("BACKUP", "Backup created!", "OK");
    }

Restore:

        private void BtnRestaurar_Clicked(object sender, EventArgs e)
    {
        var dep = DependencyService.Get<IPath>();
        string db_path = dep.GetPath("database.sqlite");
        string backup_path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData));

        var origin = File.ReadAllBytes(backup_path);
        File.WriteAllBytes(db_path, origin);

        DisplayAlert("RESTAURING", "Backup restored!", "OK");

    }

I'm getting the following exception:

System.UnauthorizedAccessException: 'Access to the path '/data/user/0/com.companyname.VendasEstoque/files/.local/share' is denied.'

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Newton
  • 65
  • 1
  • 6
  • first, you can't write to the app bundle - it's read-only. Read this: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/data-cloud/data/files?tabs=macos – Jason Oct 07 '19 at 15:25
  • second, use ReadAllBytes/WriteAllBytes to read/write db files – Jason Oct 07 '19 at 15:26
  • Thanks, I'm gonna take a look – Newton Oct 07 '19 at 15:38
  • Does Xamarin provide a way to use the actual [sqlite backup api](https://sqlite.org/backup.html)? (Recent versions can use [VACUUM INTO](https://sqlite.org/lang_vacuum.html#vacuuminto) if not) – Shawn Oct 07 '19 at 15:43
  • @Jason, I tried to do as you said, but I still got error. Gonna edit the main post with what I tried – Newton Oct 07 '19 at 16:26
  • I couldn't find any of these, @Shawn – Newton Oct 07 '19 at 16:35
  • `backup_path` is just a path, you need to include a file name – Jason Oct 07 '19 at 16:40
  • Thanks, @Jason, it worked fine! But, do you know where I can find the file location on the phone? – Newton Oct 08 '19 at 15:21

0 Answers0