Neste artigo vamos continuar mostrando como usar o Firebase Storage em uma aplicação Xamarin Forms. |
Continuando a primeira parte do artigo vamos criar agora o projeto Xamarin Forms no VS 2019 Community.
Criando o projeto Xamarin Forms
Vamos criar um novo projeto Xamarin Forms no VS 2019 Community com o nome XF_FirebaseStorage.
Nota: Verifique se você precisa atualizar as versões do Xamarin Forms e do Xamarin.Essentials
Você pode ver como criar um projeto no Xamarin Forms neste link: Criar Projeto Xamarin Forms
A seguir vamos incluir os seguinte pacotes no projeto criado:
Este plugin necessita que a versão do seu Xamarin Forms seja a versão 4.7.0 ou superior e que o Xamarin.Essentials esteja atualizado para a última versão estável.
Também será necessário realizar as configurações exibidas pelo arquivo readme.txt as quais são:
1- No projeto Android:
a) Incluir no arquivo AssemblyInfo.cs as permissões abaixo:
[assembly:
UsesFeature("android.hardware.camera", Required = false)]
[assembly: UsesFeature("android.hardware.camera.autofocus", Required = false)]
b) Incluir no arquivo AndroidManifest.xml o código a seguir:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"></meta-data>
</provider>
E também as permissões para Camera e Internet. Dessa forma o arquivo AndroidManifest.xml deve ficar assim:
<?xml
version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1"
android:versionName="1.0" package="com.companyname.xf_firebasestorage" android:installLocation="auto">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28"
/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<application android:label="XamarinFirebase.Android">
<provider android:name="android.support.v4.content.FileProvider" android:authorities="com.companyname.XamarinFirebase.fileprovider"
android:exported="false" android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"
/>
</provider>
</application>
</manifest>
Obs: A tag <provider> tem que estar dentro da tag <application>
c) Crie uma nova pasta chamada xml na pasta Resources;
d) Na pasta xml crie o arquivo file_paths.xml com o código abaixo:
<?xml
version="1.0" encoding="utf-8" ?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path name="my_images" path="Pictures"
/>
<external-files-path name="my_movies" path="Movies" />
</paths>
Nota: Ao criar o arquivo file_paths.xml verifique se a build action esta definida para AndroidResource.
Para mais detalhes acesse o link: https://developer.android.com/training/camera/photobasics.html
Criando a página principal do projeto
A seguir vamos criar a página principal da aplicação usando o arquivo MainPage.xaml do projeto e incluindo o código abaixo:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="XF_FirebaseStorage.MainPage">
<StackLayout>
<StackLayout>
<StackLayout HorizontalOptions="Center" VerticalOptions="Start">
<Image Margin="0,0,0,10" HeightRequest="100" Source="firebase.png" ></Image>
<Label Margin="0,0,0,10" Text="Firebase Storage" FontAttributes="Bold"
FontSize="Large" TextColor="Gray" HorizontalTextAlignment="Center" />
<Image x:Name="imagemSelecionada" HeightRequest="150"></Image>
<Entry x:Name="txtNomeArquivo" Placeholder="Nome do arquivo"></Entry>
<StackLayout HorizontalOptions="CenterAndExpand" Orientation="Horizontal">
<Button x:Name="btnPega" WidthRequest="200" Text="Pegar Imagem"
Clicked="BtnSelecionaImagem_Clicked"/>
<Button x:Name="btnUpload" WidthRequest="200" Text="Enviar Imagem"
Clicked="BtnUpload_Clicked" />
</StackLayout>
<StackLayout HorizontalOptions="CenterAndExpand" Orientation="Horizontal">
<Button x:Name="btnDownload" WidthRequest="200" Text="Download"
Clicked="btnDownload_Clicked" />
<Button x:Name="btnDeleta" WidthRequest="200" Text="Deletar Imagem"
Clicked="btnDeleta_Clicked" />
</StackLayout>
<Label x:Name="lblPath"></Label>
</StackLayout>
</StackLayout>
</StackLayout>
</ContentPage>
|
Abaixo temos a figura gerada pelo XAML Preview exibindo uma amostra da nossa página:
O fluxo de execução é o seguinte:
Agora vamos criar uma pasta Services no projeto e nesta pasta criar o arquivo FirebaseStorageService onde vamos definir os métodos usando a API do FirebaseStorage para realizar as operações para enviar, deletar e obter imagens.
Abaixo temos o código da classe FirebaseStorageService :
using Firebase.Storage;
using System;
using System.IO;
using System.Threading.Tasks;
namespace XF_FirebaseStorage.Services
{
public class FirebaseStorageService
{
FirebaseStorage firebaseStorage = new FirebaseStorage("xamarinimag******o***");
public async Task<string> UploadFile(Stream fileStream, string fileName)
{
try
{
var imageUrl = await firebaseStorage
.Child("Paisagens")
.Child(fileName)
.PutAsync(fileStream);
return imageUrl;
}
catch(Exception ex)
{
throw ex;
}
}
public async Task<string> GetFile(string fileName)
{
try
{
return await firebaseStorage
.Child("Paisagens")
.Child(fileName)
.GetDownloadUrlAsync();
}
catch(Exception)
{
throw;
}
}
public async Task DeleteFile(string fileName)
{
try
{
await firebaseStorage
.Child("Paisagens")
.Child(fileName)
.DeleteAsync();
}
catch (Exception)
{
throw;
}
}
}
}
|
Dois pontos importantes a destacar aqui:
1- Na instância da classe FirebaseStorage você deve usar a URI do seu projeto Firebase Storage;
2- Estamos definindo o nó Paisagens a partir do qual vamos incluir as imagens no Storage;
Para concluir vamos definir o código no arquivo MainPage.xaml.cs de cada um dos eventos Click dos botões de comando:
using Plugin.Media;
using Plugin.Media.Abstractions;
using System;
using System.ComponentModel;
using System.IO;
using Xamarin.Forms;
using XF_FirebaseStorage.Services;
namespace XF_FirebaseStorage
{
[DesignTimeVisible(false)]
public partial class MainPage : ContentPage
{
FirebaseStorageService fbStorageService = new FirebaseStorageService();
MediaFile arquivoMediaFile;
public MainPage()
{
InitializeComponent();
}
private async void BtnSelecionaImagem_Clicked(object sender, EventArgs e)
{
await CrossMedia.Current.Initialize();
try
{
arquivoMediaFile = await Plugin.Media.CrossMedia.Current.PickPhotoAsync(
new Plugin.Media.Abstractions.PickMediaOptions
{
PhotoSize = Plugin.Media.Abstractions.PhotoSize.Medium
});
if (arquivoMediaFile == null)
return;
imagemSelecionada.Source = ImageSource.FromStream(() =>
{
var imageStram = arquivoMediaFile.GetStream();
return imageStram;
});
}
catch (Exception ex)
{
await DisplayAlert("Sucesso", ex.Message, "OK");
}
}
private async void BtnUpload_Clicked(object sender, EventArgs e)
{
if (arquivoMediaFile == null)
{
await DisplayAlert("Erro", "Erro ao selecionar imagem.", "OK");
return;
}
else
{
await fbStorageService.UploadFile(arquivoMediaFile.GetStream(),
Path.GetFileName(arquivoMediaFile.Path));
await DisplayAlert("Sucesso", "Imagem enviada ao Storage com sucesso.", "OK");
}
}
private async void btnDownload_Clicked(object sender, EventArgs e)
{
string path = await fbStorageService.GetFile(txtNomeArquivo.Text);
if (path != null)
{
lblPath.Text = path;
await DisplayAlert("Sucesso", "Arquivo : " + path + " baixado", "OK");
}
}
private async void btnDeleta_Clicked(object sender, EventArgs e)
{
await fbStorageService.DeleteFile(txtNomeArquivo.Text);
lblPath.Text = string.Empty;
await DisplayAlert("Sucesso", "Deletado", "OK");
}
}
|
Neste código estamos usando os métodos criados no serviço FirebaseStorageService para enviar e obter imagens.
Executando o projeto iremos obter o seguinte resultado:
Nota: Como estou usando o emulador não existem imagens na câmara.
A figura abaixo mostra como será visualizada a estrutura de dados no Storage:
Pegue o código do projeto compartilhado aqui : XF_FirebaseStorage.zip
"Tendo sido,
pois, justificados pela fé, temos paz com Deus, por nosso Senhor Jesus Cristo;"
Romanos 5:1
Referências:
NET - Apresentando o padrão Model-View-ViewModel
Xamarin Forms - MVVM - Macoratti.net
NET - O padrão MVVM (Model-View-ViewModel) revisitado
Xamarin Forms - MVVM - A interface ICommand
Padrão de Projeto - Aprendendo o padrão MVVM ...