Paolo Dell'Aguzzo
  • Chi sono
  • Cosa offro
  • Portfolio e Carriera
    • Carriera
    • Portfolio
  • PRESS e Guest Post
  • Contatti
  • Blog
Paolo Dell'Aguzzo
  • Chi sono
  • Cosa offro
  • Portfolio e Carriera
    • Carriera
    • Portfolio
  • PRESS e Guest Post
  • Contatti
  • Blog
Gen 10

React Native: come salvare le foto su Firebase Storage

  • 10/01/2018
  • Paolo Dell'Aguzzo
  • No Comments
  • Programmazione
  • app, firebase, react, react native

In questo articolo vediamo come salvare le foto su Firebase Storage. Anche se questo articolo è parte di una guida ben più ampia che ti fa imparare React Native puoi tranquillamente seguire quanto scritto ed applicare facilmente le brevi procedure necessarie per imparare come salvare le foto su Firebase Storage.

Per questa app stiamo utilizzando il pacchetto firebase disponibile tramite NPM e già descritto in questo articolo.

Come salvare le foto su Firebase Storage

Per scoprire come salvare le foto su Firebase Storage è necessario che prima ti ricordi di alcune cose già descritte nell’articolo relativo a Firebase ed al suo setup iniziale che puoi trovare a questo indirizzo. Firebase Storage è uno spazio nel Cloud costruito per far ospitare file di ogni tipo e specialmente immagini e video.

Il pacchetto firebase installato in precedenza tramite NPM mette a disposizione infatti tutte le API necessarie per comunicare sia con il realtime database, come abbiamo visto quì, che con Firebase Storage come vedremo tra poco.

Segui i passi necessari in ordine e vedrai che anche tu potrai capire come salvare le foto su Firebase Storage.

Installare le dipendenze

Per prima cosa abbiamo bisogno della dipendenza verso react-native-fetch-blob che ci fornisce alcune funzionalità di accesso, download, upload e conversione dei file. Per installarlo puoi digitare da terminale (sempre posizionandoti nella cartella root del tuo progetto):

Development Category (English)728x90

npm install --save react-native-fetch-blob

Dunque è necessario effettuare il link delle librerie:

react-native link

Modifica dei file

Per capire come salvare le foto su Firebase Storage è necessario che apri il file firebase.js modificandolo in questo modo:

import * as firebase from 'firebase';
import RNFetchBlob from 'react-native-fetch-blob';


const firebaseConfig = {
    apiKey: "tuoi_dati",
    authDomain: "tuoi_dati",
    databaseURL: "tuoi_dati",
    projectId: "tuoi_dati",
    storageBucket: "tuoi_dati",
    messagingSenderId: "tuoi_dati"
};

const firebaseApp = firebase.initializeApp(firebaseConfig);

export default class Firebase{

  constructor(){

    firebaseApp.auth().onAuthStateChanged(function(user) {
      if (user) {
        //Fai qualcosa..
      } else {
        this.auth();
      }
    }.bind(this));
  }

  auth(){
    firebase.auth().signInWithEmailAndPassword("tuoi_dati", "tuoi_dati").catch(function(error) {
      console.error("Errore durante autenticazione...", error.code, error.message);
    });
  }

  print(refValue){
    console.log("RefValue print: ", refValue);

    this.itemsRef = firebaseApp.database().ref(refValue);
    console.log("Ecco la reference: ", this.itemsRef);

    this.itemsRef.on('value', function(elem){
      console.log("elem: ", elem);

      elem.forEach(function(e){
        console.log("e.val() ", e.val());
        console.log("e.val().name ", e.val().name);
        console.log("e.key ", e.key);
      });
    });
  }

  save(refValue, newDataItem){
    console.log("RefValue save: ", refValue);

    firebaseApp.database().ref(refValue + newDataItem.id).set(newDataItem).then(function(result){
        console.log("Salvato con successo..!");
      }.bind(this), function(error){
        console.error("Errore durante il salvataggio..", error);
      }.bind(this));
  }

  saveImage(settings, path){
    const Blob = RNFetchBlob.polyfill.Blob
    const fs = RNFetchBlob.fs
    window.XMLHttpRequest = RNFetchBlob.polyfill.XMLHttpRequest
    window.Blob = Blob

    let mime = "image/jpg";

    const imageRef = firebase.storage().ref('images').child(settings.id + ".jpg");

    fs.readFile(path, 'base64').then(function(data){
        return Blob.build(data, { type: `${mime};BASE64` });
    }).then(function(blob){
        var uploadBlob = blob
        return imageRef.put(blob, { contentType: mime })
      }).then(function(){
        uploadBlob.close()
        return imageRef.getDownloadURL()
      }).then(function(url){
        console.log(url);
        
      }).catch(function(error){
        console.log("Errore durante il salvataggio su Firebase Storage dell'immagine: ", error);
      });
  }
}

E’ rimasto quasi tutto invariato tranne alcune nuove righe aggiunte:

Deep Learning Specialization on Coursera
  • Importiamo react-native-fetch-blob
  • Abbiamo creato un nuovo metodo saveImage che riceve in ingresso dei settings ed un percorso

All’interno del metodo saveImage dichiariamo il Blob ed Fs che ci servirà per accedere al file in memoria. Facciamo lo stesso su “window” così da poter provare il tutto in debug. Dunque definiamo un “mime” e recuperiamo il riferimento alla cartella delle immagini su Firebase Storage. Se accedi a Firebase, entri nel tuo progetto e selezioni “Storage” dal menù laterale sinistro, inizialmente vedrai tutto vuoto. Ciò vuol dire che alla prima chiamata di questo metodo verrà creata la cartella “images” contenente l’immagine. La nostra immagine avrà come nome l’id più l’estensione.
Dunque per prima cosa leggiamo il file in formato base64 e una volta conclusa l’operazione di lettura creiamo un blob. Una volta creato il blob lo teniamo da parte(nella var uploadBlob) e chiamiamo il metodo put di imageRef inviando a Firebase sia il blob che dei metadati (un oggetto con proprietà contentType). Una volta fatto ciò chiudiamo il blob (ecco perché lo teniamo salvato in una variabile a parte) e ritorniamo l’url per il download dell’immagine che poi andiamo a scrivere nei log.

Ma chi è Settings?

Settings è un record della tabella Settings che abbiamo creato in questo articolo.

Prima di capire come salvare le foto con Firebase Storage è necessario che ti spiego cos’è Settings. Questa tabella contiene per scopo dimostrativo i campi id e photoPath. Quello che ci interessa a noi è quindi andare a scrivere in questa tabella il percorso della foto scattata. L’id generato ci farà da riferimento anche nella cartella images di Firebase Storage.

Dunque se non sei interessato puoi sostituire “settings.id” con qualcos’altro e puoi anche decidere di non far ricevere come parametro d’ingresso i settings al metodo saveImage.

Per chi sta seguendo punto per punto la guida è necessario invece creare la cartella “settings” dentro a “common/database”. All’interno della cartella “settings” è necessario creare il file settingsModel.js che conterrà:

import DatabaseHelper from '../databaseHelper';

class SettingsModel {
  constructor(photoPath) {
    this.id = DatabaseHelper.guid();
    this.photoPath = photoPath;
  }
}

module.exports = SettingsModel;

Non è altro che una classe costituita da id e photoPath. L’id viene generato da un DatabaseHelper descritto negli articoli precedenti.

Dunque è necessario creare il file settingsService.js:

import Database from './../database';
import SettingsModel from './settingsModel';

let repository = Database.getRepository();


let SettingsService = {
  get: function() {
    return repository.objects('Settings');
  },

  save: function(setting) {
    repository.write(() => {
      repository.create('Settings', setting);
    })
  },

  update: function(callback) {
    if (!callback) return;
    repository.write(() => {
      callback();
    });
  }
};


module.exports = SettingsService;

Banalmente implementa i metodi get, save ed update.

L’ultimo step

Ora non ci resta che collegare il tutto e fare le chiamate necessarie dal file photo.js per imparare come salvare le foto con Firebase Storage. Questo file contiene la fotocamera ed inoltre mostra istantaneamente la foto appena scattata.

Adesso lo modificheremo per mostrare la foto salvata (quindi una volta scattata la prima foto chiudendo ed aprendo l’app vedremo sempre l’ultima foto scattata). Inoltre chiameremo il metodo del file firebase.js visto prima per salvare la foto su Firebase Storage.

Apri il file photo.js ed importa Firebase, SettingsModel e SettingsService. Dunque bisogna modificare il metodo takePicture che chiamerà due metodi (writeOnRealm e writeOnFirebasePath). Vediamo insieme il codice completo di photo.js:

import React, { Component } from 'react';
import {
  StyleSheet,
  Text,
  View,
  Image,
  Platform
} from 'react-native';

import Camera from 'react-native-camera';

import Firebase from "../../common/firebase/firebase";
import SettingsService from '../../common/database/settings/settingsService';
import SettingsModel from '../../common/database/settings/settingsModel';

export default class Photo extends Component<{}> {
  constructor(props){
    super(props);

    this.camera = undefined;
    this.firebase = new Firebase();

    let settings = SettingsService.get();

    this.state = {
      settings: settings.length > 0 ? settings[0] : undefined,
    }
  }

  onBarCodeRead(e) {
    console.log(
        "Barcode Found! ",
        "Type: " + e.type + "\nData: " + e.data
    );
  }

  takePicture() {
    const options = {};
    //options.location = ...
    if(this.camera){
      this.camera.capture({metadata: options}).then(function(data){
        console.log(data);

        this.writeOnRealm(data.path);

        var firebasePath = Platform.OS === 'ios' ? data.path : data.path.substring(7);
        this.writeOnFirebasePath(firebasePath);

      }.bind(this)).catch(function(err){ 
        console.error(err);
      }.bind(this));
    }
  }

  writeOnRealm(path){
    var settings = this.state.settings;

    if(settings !== undefined){
      SettingsService.update(() => {
        settings.photoPath = path;
      });
    }else{
      var settingsModel = new SettingsModel(path);
      SettingsService.save(settingsModel);
    }

    this.setState({settings: SettingsService.get()[0]});
  }

  writeOnFirebasePath(path){
    this.firebase.saveImage(this.state.settings, path); 
  }

  render() {
    return (
      <View style={styles.container}>
        <Camera ref={(cam) => {
            this.camera = cam;
          }}
          onBarCodeRead={this.onBarCodeRead.bind(this)}
          style={styles.preview}
          aspect={Camera.constants.Aspect.fill}
          captureTarget = {Camera.constants.CaptureTarget.disk}>
          <Text style={styles.capture} onPress={this.takePicture.bind(this)}>[CAPTURE]</Text>
        </Camera>
        <Image source={{ uri: this.state.settings ? this.state.settings.photoPath : undefined }} style={styles.preview}/>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#F5FCFF',
  },
  preview: {
    flex: 1,
    justifyContent: 'flex-end',
    alignItems: 'center'
  },
  capture: {
    flex: 0,
    backgroundColor: '#fff',
    borderRadius: 5,
    color: '#000',
    padding: 10,
    margin: 40
  }
});

Dopo aver importato le nuove dipendenze come descritto poco fa abbiamo modificato il metodo takePicture. Come puoi vedere viene chiamato per primo writeOnRealm che in ordine:

  • Controlla se avevamo già i settings
  • In caso di risposta positiva esegue un update che consiste nel cambio di path
  • Altrimenti crea un nuovo SettingsModel e lo salva
  • Dunque nello state imposta in settings quanto abbiamo salvato

Dunque chiamiamo il metodo writeOnFirebasePath che:

  • Prende come parametro il path dell’immagine (in questo caso con subString(7) per Android, ovvero eliminando i primi 7 caratteri che sono “file://”)
  • Chiama il metodo saveImage scritto prima in firebase.js inviando i settings ed il percorso dell’immagine

Nota Bene: Ho utilizzato Platform importato da react-native per capire se ci troviamo su iOS o su Android.

Nota Bene 2: Quando si utilizza il simulatore iOS è possibile che venga cambiato il percorso ad ogni riavvio quindi sarebbe meglio determinare ogni volta il percorso di base da zero e scrivere sul database solo la parte statica.

Qualche prova

Facciamo qualche prova insieme per vedere cosa accade.

Android

Fai partire la tua app con “react-native run-android” e prova a scattare una foto.

Android fotocamera react native

Vedrai che da adesso in poi ci sarà sempre una foto caricata sotto alla fotocamera ed inoltre entrando in Firebase Storage vedrai la cartella “images” con dentro la tua immagine:

Firebase Storage immagini foto

Ogni volta che salverai la foto andrai a sovrascrivere questa su Firebase poiché la foto avrà sempre lo stesso nome. Lo stesso vale per il path salvato sul database nella tabella Settings visto che chiameremo il metodo “update” di SettingsService.

Abbiamo già visto come far funzionare la fotocamera in questo articolo. Ovviamente in un’app con degli utenti reali è necessario inserire delle barre di caricamento, una gestione degli errori più strutturata e specialmente stare attenti alle dimensioni delle immagini caricate. Questo però meriterebbe una guida ben più ampia che al momento ti distrarrebbe e basta.

iOS

Fai partire il simulatore iOS con “react-native run-ios” e vai a scattare la tua prima foto.

ios react native camera

Entrando su Firebase Storage vedrai ora anche la nuova foto scattata da questo dispositivo:

iOS Firebase Storage

Conclusioni

In questo articolo hai imparato come salvare le foto su Firebase Storage ed hai potuto toccare con mano il funzionamento sia su iOS che su Android. Abbiamo visto davvero molto in questa guida per imparare React Native e probabilmente con il tempo ci sarà ancora qualcosa di nuovo da aggiungere.

Su Udemy puoi trovare tanti corsi interessanti nei riguardi di React Native:

  • The Complete React Native and Redux Course
  • React Native: Advanced Concepts
  • Create your first React Native App

Non ti perdere quindi la guida salvandoti il link alla guida per imparare React Native.

Se sei interessato continua a seguirmi, magari iscriviti alla newsletter così da non dimenticarti di questa guida. Nel caso in cui ancora non ti senti pronto con React puoi sempre seguire questa guida e poi potrai imparare React Native.

Se vuoi rimanere aggiornato sul continuo di questa guida ti consiglio di iscriverti alla newsletter. Mando da 1 a 4 mail al mese e normalmente invio risorse gratuite e riservate solo agli iscritti. Invio anche la lista degli articoli di maggiore impatto, come questo. Se non troverai gli articoli potrai recuperarli dalla mail in questo modo ?

Per dubbi o domande non esitare a scrivermi nei commenti ?

Se ti è piaciuto l’articolo seguimi su Facebook e Twitter oppure rimani sempre aggiornato con la newsletter (da 1 a 4 mail al mese!).

Prossimo articolo della guida: React Native: perché usare React Native Firebase

Commenti

Condividi:

  • Fai clic qui per condividere su Twitter (Si apre in una nuova finestra)
  • Fai clic per condividere su Facebook (Si apre in una nuova finestra)
  • Fai clic qui per condividere su Tumblr (Si apre in una nuova finestra)
  • Fai clic qui per condividere su LinkedIn (Si apre in una nuova finestra)
  • Fai clic qui per condividere su Pinterest (Si apre in una nuova finestra)
  • Fai clic per condividere su WhatsApp (Si apre in una nuova finestra)
  • Fai clic per condividere su Telegram (Si apre in una nuova finestra)
  • Clicca per condividere su Skype (Si apre in una nuova finestra)
  • Fai clic qui per stampare (Si apre in una nuova finestra)

Correlati

  • Facebook
  • Twitter
  • Tumblr
  • Pinterest
  • Google+
  • LinkedIn
  • E-Mail
Paolo Dell'Aguzzo

About The Author

Sono sempre stato affascinato dal marketing e dall'informatica a tal punto di unire le due passioni :) Se ti piace l'articolo fammelo sapere in un commento :)

Related Posts

  • React Native: come modificare lo schema Realm10/01/2018
  • React Native: Come scattare foto con react-native-camera09/01/2018
  • React Native: Salvare i dati con Firebase08/01/2018
  • React Native: Cos’è Firebase e setup iniziale08/01/2018

Fammi sapere cosa ne pensi :) Annulla risposta

Impara ReactJS imparare react
I 10 + 1 Libri che Dovrebbe Leggere Ogni Programmatore libri programmatore
Newsletter

Seguimi su Facebook :)

Facebook Pagelike Widget
Impara React Native imparare react native
10 Cose per Stare Più Comodo in Ufficio stare più comodo in ufficio
Impara a Creare un Tema Wordpress imparare creare tema wordpress
Udemy I Migliori Corsi per Programmatori udemy corsi programmatori
UX: Perché la User Experience è Importante UX importante e cos'è
Metodologie Agili e Lean: Come migliorare la tua azienda metodologie agili
Libri per Imparare JavaScript Imparare JavaScript libri

Articoli recenti

  • I principali engine utilizzati per lo sviluppo di videogiochi
  • Dalla visione alla realtà: Lo sviluppo di videogiochi dal punto di vista di un programmatore
  • 8 consigli per migliorare la tua SEO Locale

Categorie

  • CSS
  • Interviste
  • Java
  • Lavoro
  • Normative
  • Personale
  • Programmazione
  • Strategia & Marketing
  • Tech
  • Web Design
  • Wordpress
Paolo Dell'Aguzzo
Programmatore Software - Marotta di Mondolfo, Pesaro e Urbino
P. IVA: IT02758450429
Mail: info@paolodellaguzzo.com
Via Litoranea, 284/C - Marotta (PU)
Privacy Policy
Cookie Policy
In qualità di Affiliato Amazon, ricevo un guadagno per ciascun acquisto idoneo
Amazon e il logo Amazon sono marchi registrati di Amazon.com, Inc. o delle sue affiliate
Programmatore Senigallia, Ancona - Siti web, app iOS e Android, gestionali ReactJS, React Native, Java, SQL, PL/SQL, Heroku

 

Caricamento commenti...