JavascriptProva

venerdì 2 settembre 2016

Archiviazione di immagine su Firebase senza far ricorso allo storage. Esperimento riuscito!

dataSnapshot.
Per prima cosa, voglio capire quando viene archiviata una classe come viene archiviata.
Inizio con un codice semplicissimo.
reference.child("persona").setValue("fanqulo");
E vediamo in termini di key-value cosa ne viene fuori.



Ecco, viene una coppia key-value in cui key è il nome del nodo e value è il valore.

Ora vediamo se al posto del "fanqulo" ci metto una istanza di classe:
        reference.child("persona").setValue(new Persona("Mario","Rossi","Operaio"));




    }

    public class Persona {
        public String nome;
        public String cognome;
        public String professione;
        public Persona(String nome, String cognome, String professione){
            this.nome=nome;
            this.cognome=cognome;
            this.professione=professione;
        }




Ora vediamo di ottenere key e value per la prima e per la seconda:
Per la prima:
        System.out.println(reference.child("persona").getKey());
        
        reference.child("persona").addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                System.out.println(dataSnapshot.getValue());
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
09-02 23:28:40.210 25588-25588/com.example.antonello.palestradatabase I/System.out: persona
09-02 23:28:40.330 25588-25588/com.example.antonello.palestradatabase D/OpenGLRenderer: Enabling debug mode 0
09-02 23:28:40.440 25588-25588/com.example.antonello.palestradatabase I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@41e806f8 time:10096272
09-02 23:28:50.390 25588-25608/com.example.antonello.palestradatabase W/DynamiteModule: Local module descriptor class for com.google.firebase.auth not found.
09-02 23:29:00.280 25588-25588/com.example.antonello.palestradatabase I/System.out: fanqulo

Ora per la seconda (le istruzioni sono le stesse):
09-02 23:36:58.086 31230-31230/com.example.antonello.palestradatabase I/System.out: persona
09-02 23:36:58.116 31230-31230/com.example.antonello.palestradatabase I/System.out: {professione=Stronzo, cognome=Iaccarino, nome=Antonello}
Sì, perfetto.


Ora, in questo dataSnapshot, voglio vedere solo la professione.
Scrivo un codice che nell'ambito del dataSnapshot mi identifichi un solo valore.
        reference.child("persona").setValue(new Persona("Antonello","Iaccarino","Stronzo"));

        System.out.println(reference.child("persona").child("professione").getKey());

        reference.child("persona").child("professione").addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                System.out.println(dataSnapshot.getValue());
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
E vediamo.

09-02 23:44:24.031 6244-6244/com.example.antonello.palestradatabase I/System.out: professione
09-02 23:44:24.211 6244-6244/com.example.antonello.palestradatabase I/System.out: Stronzo
Perfetto!

Ora mi predispongo al posto della professione, un'immagine!
La classe è questa:
    public class Persona {
        public String nome;
        public String cognome;
        public String ritratto;
        public Persona(String nome, String cognome, String ritratto){
            this.nome=nome;
            this.cognome=cognome;
            this.ritratto=ritratto;
        }

    }
E me la inizializzo così:
        Bitmap bitmap= BitmapFactory.decodeResource(getResources(),R.drawable.facciadaculo);
        ByteArrayOutputStream baos=new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG,100,baos);
        byte[] byteImage=baos.toByteArray();
        String stringImage= Base64.encodeToString(byteImage,Base64.DEFAULT);

        Persona persona=new Persona("Antonello","Iaccarino",stringImage);
        reference.child("persona").setValue(persona);
Vediamo cosa viene archiviato su Firebase...



Dunque l'immagine viene archiviata come stringa, a quanto pare.
Adesso commentizzo il codice che è stato usato per l'archiviazione e scrivo un codice che avrebbe lo scopo di riconvertire la stringa in immagine e farlo apparire su una imageView che ho sull'activity.
Provo prima a riportare il valore in stringa:
        reference.addValueEventListener(new ValueEventListener(){

            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                String stringResult=(String)dataSnapshot.getValue();
                System.out.println(stringResult);
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        })
Ho ottenuto un errore perché dataSnapshot.getValue() non è castabile a String.
Ho fatto altri tentativi vari finché ho trovato il modo: usare semplicemente dataSnapshot.toString():
        reference.addValueEventListener(new ValueEventListener(){

            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                String stringResult=dataSnapshot.toString();
                System.out.println(stringResult);
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
E ottengo questo:
09-03 00:02:40.611 20611-20611/com.example.antonello.palestradatabase I/System.out: DataSnapshot { key = null, value = {persona={ritratto=/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
09-03 00:02:40.611 20611-20611/com.example.antonello.palestradatabase I/System.out: AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEB
09-03 00:02:40.611 20611-20611/com.example.antonello.palestradatabase I/System.out: AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAHgAeADASIA
09-03 00:02:40.611 20611-20611/com.example.antonello.palestradatabase I/System.out: AhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQA
09-03 00:02:40.611 20611-20611/com.example.antonello.palestradatabase I/System.out: AAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3
09-03 00:02:40.611 20611-20611/com.example.antonello.palestradatabase I/System.out: ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWm
09-03 00:02:40.611 20611-20611/com.example.antonello.palestradatabase I/System.out: p6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEA
09-03 00:02:40.611 20611-20611/com.example.antonello.palestradatabase I/System.out: AwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSEx
09-03 00:02:40.611 20611-20611/com.example.antonello.palestradatabase I/System.out: BhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElK
.....
.....
Mi accorgo che ho applicato il listener a reference e non a un child.
Correggo:
        reference.child("persona").child("ritratto").addValueEventListener(new ValueEventListener(){

            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                String stringResult=dataSnapshot.toString();
                System.out.println(stringResult);
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
E vediamo...

09-03 00:02:40.641 20611-20611/com.example.antonello.palestradatabase I/System.out: 4PJG7057cubcneLj7y01b3kvLfX53u3dM+jxSUqaflzfi7X9bddnfS6d/OfEPiOOyJcA4BPQHn5z
09-03 00:02:40.641 20611-20611/com.example.antonello.palestradatabase I/System.out: gnk8Hn6+vHGDD4+WeMx4IKp8p2+pbPUk/wAI5/2hnOMnq9QsUO4FVbp1UHHX1OPzz16kZauRu9MV
09-03 00:02:40.641 20611-20611/com.example.antonello.palestradatabase I/System.out: 0YooyEkzhQOrHHQccI+D0x1I3HP0WGpJZhiJ8y/2LDTpvT+Jzxqw5r3fI17Tb3r8trq6Z5DnbGvS
09-03 00:02:40.641 20611-20611/com.example.antonello.palestradatabase I/System.out: +/4cy2a62jpvq9U02foF+wJ4kGpfGKO2Xhv7AuxkA/8AP9p+D16kdvTHXPH7fXaIiz3KqNs6hUAx
09-03 00:02:40.641 20611-20611/com.example.antonello.palestradatabase I/System.out: kNnAOM+zZyfTOSBn8Df2CBJp/wAZkkiG6X+wbvICnvqFhgcH0Un8eeRz+8Om2+qzWsstwgxtOMke
09-03 00:02:40.641 20611-20611/com.example.antonello.palestradatabase I/System.out: pxgF8fh15Ygkmv3fw7o+w4Qw8FLn58TXrXslb2koS5bXeq77tNNpPmv8NncubMKmlrSfW9/ft29H
....
....
Non ci entra nella finestra LogCat, per cui credo sia stato troncato l'inizio...

Va bene, andiamo sulla fiducia e partiamo.
Riconversione di questo po' po' di stringone in immagine: facciamo il tentativo.
        reference.child("persona").child("ritratto").addValueEventListener(new ValueEventListener(){

            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                String stringResult=dataSnapshot.toString();
                byte[] byteResult= Base64.decode(stringResult,Base64.DEFAULT);
                Bitmap bitmapResult= BitmapFactory.decodeByteArray(byteResult,0,byteResult.length);
                imageView.setImageBitmap(bitmapResult);
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
E vediamo se appare l'immagine nella ImageView...

No! Illegal Argument per Base64.decode!

Ecco che però mi accorgo, riducendo la compressione della bitmap e ottenendo quindi un file più corto, che ho ottenuto anche la key del dataSnapshot, e quindi quella che veniva presentata a Base64 non era la stringa pura!
Dunque metto getValue:
        Bitmap bitmap= BitmapFactory.decodeResource(getResources(),R.drawable.facciadaculo);
        ByteArrayOutputStream baos=new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG,10,baos);
        byte[] byteImage=baos.toByteArray();
        String stringImage= Base64.encodeToString(byteImage,Base64.DEFAULT);

        Persona persona=new Persona("Antonello","Iaccarino",stringImage);
        reference.child("persona").setValue(persona);


        reference.child("persona").child("ritratto").addValueEventListener(new ValueEventListener(){

            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                String stringResult=dataSnapshot.getValue().toString();
                byte[] byteResult=Base64.decode(stringResult,Base64.DEFAULT);
                Bitmap bitmapResult=BitmapFactory.decodeByteArray(byteResult,0,byteResult.length);
                imageView.setImageBitmap(bitmapResult);
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });


E finalmente l'esperimento è riuscito!!!



Riprovo commentizzando la parte che archivia.

Perfetto!

1 commento: