ReactNative oraz Firebase - jak dodawać zdjęcia do FIrebase Storage?

0

Cześć!

Mam do was pytanie odnośnie Storage oferowanego przez Firebase. Jestem w trakcie tworzenia projektu, i nie mogę sobie poradzić z dodawaniem grafik do oferowanego Storage. Projekt tworzę na zajęcia, także więc jest to aplikacja w ReactNative, w połączniu z Firebase tworzona pod system Android (ponieważ iOS fizycznie nie posiadam). Projekt postawiony jest w oparciu o Expo, a działanie programu najczęściej sprawdzam na emulatorze z Android Studio (Nexus 4). Aktualnie zrobiłem już pobieranie grafiki z galerii:

_getPhotoLibrary = async () => {
        let result = await ImagePicker.launchImageLibraryAsync({
            allowsEditing: false,
            aspect: [4, 3]
        });
        if (!result.cancelled) {
            this.setState({ image: result.uri });
        }
    }

A w taki sposób próbuje grafikę z galerii dodać do Storage w FIrebase:

dodajFoto = () => {

        //pobranie nazwy zdjęcia
        const splittedl = this.state.image.split('/').length;
        let name = this.state.image.split('/')[splittedl - 1];
        console.log(this.state.image);
        console.log(name);

        //dodanie zdjęcia do Storage
        const reference = firebase.storage().ref().child(name);

        const task = reference.put({ data: { uri: this.state.image } }, { contentType: 'image/jpeg' });

        task.on('state_changed', taskSnapshot => {
            console.log(`${taskSnapshot.bytesTransferred} transferred out of ${taskSnapshot.totalBytes}`);
        });

        task.then((snapshot) => { console.log(`Foto has been successfully uploaded.`); }).catch((e) => console.log('uploading image error => ', e));

    }

Niestety za każdym razem jak dodaje grafikę, to pisze że dodano 0 bajtów do firebase. W Storage zostaje utworzony plik .jpg ważący 9kb i niestety na tym się kończy. Próbowałem już wielu sposobów z Internetu niestety każdy zawodzi. Może ktoś z was widzi tu jakiś błąd i mi pomoże co mam zmienić żeby zdjęcie z galerii telefonu dodawało się do tego właśnie Storage. Odnośnie funkcji "put()" którą używam do dodawania zdjęcia, tylko ona aktualnie jako jedyna działa mi podczas dodawania. W Internecie większość osób pisze o funkcji putFile(), aczkolwiek ona u mnie nie działa :/ Jest to moje pierwsze doświadczenie z react Native, oraz aplikacjami mobilnymi przez to też troche jest to dla mnie problematyczne. Z góry dziękuję za pomoc.

1

Mówisz, że dostajesz informacje o 0 bajtach dodanych do firebase, więc wnioskuję, że mowa tu o komunikacie w on, a potem widzisz then, czy może jednak łapiesz jakiś błąd w catch?
Jeśli dodano 0 bajtów, to znaczy że najpewniej komunikacja z firebase jest, ale coś nie gra z samym obrazem, jego załadowaniem, pobraniem.
Po drugie: piszesz, że firebase zwraca sukces, ale loguje 0 bajtów, ale w Storage widzisz 9kB. A ile powinien ważyć obrazek?
Po trzecie: trochę nie rozumiem - piszesz, że put, który użyłeś "działa", ale w Storage masz 9kB, natomiast firebase loguje 0 i co masz na myśli "na tym się kończy"? Chciałeś wrzucić obrazek do Storage i tam go widzisz...


Uwagi na boku:

  • używaj const zamiast let tam gdzie to możliwe
  • trochę przekombinowałeś obsługę taska, w sensie: dziwnie to rozbiłeś. Można to było zrobić w jednej instrukcji w trzech linijkach.
1

Jak się nazywa moduł ktorego używasz? Sprawdzałeś dokumentację czy wspiera RN?

Edit: czy to nie czasami to: https://github.com/fris-fruitig/react-firebase-file-uploader/issues/12

0

@Bartosz36: Tak tak jestem tego świadomy że trochę przekombinowałem, ale szczerze mówiąc to moja pierwsza styczność z React Nativem i szczerze mówiąc uczę się wszystkiego. Odnosząc się do pytania o plik 9kB, to chodziło mi o to że tworzył się plik bez zawartości, miał nazwę, miał rozszerzenie, oraz określony typ, ale nie zawierał jakiejkolwiek zawartości. Pogrzebałem trochę w YouTube, i znalazłem jeden poradnik który rozwiązał mój problem, aktualnie kod wygląda następująco:


_getPhotoLibrary = async () => {
        let result = await ImagePicker.launchImageLibraryAsync({
            allowsEditing: false,
            aspect: [4, 3]
        });
        if (!result.cancelled) {
            this.setState({ image: result.uri });
        }
    }

    dodajFoto = async () => {

        const splittedl = this.state.image.split('/').length;
        let name = this.state.image.split('/')[splittedl - 1];

        const response = await fetch(this.state.image);
        const blob = await response.blob();
        let ref = firebase.storage().ref().child(name);
        ref.put(blob).then(() => { 
            Alert.alert("dodano"); 
            firebase.storage().ref().child(name).getDownloadURL().then(
                url => { this.setState({ imageDownloadURL: url }) }) 
            });
    }

Funkcja getPhotoLibrary, odpowiedzialna jest za pobieranie zdjęcia z galerii w telefonie za pomocą modułu "expo-image-picker". Funkcja dodajFoto, służy do umieszczenia wybranego zdjęcia w Firebase Storage. Niestety rozszerzenie "expo-image-picker" nie posiada opcji pobierania nazwy zdjęcia, więc pobieram ją samemu za pomocą zmiennych "splittedl" oraz "name". Reszta kodu pochodzi z tutoriala, który nie wiem czy dobrze rozumiem, ale chyba pobiera zdjęcie za pomocą funkcji fetch, a następnie to zdjęcie jest parsowane do formatu "blob". W tym formacie zdjęcie dodawane jest do Firebase Storage, a także pobieram link do pobrania zdjęcia, który domyślnie trafia do bazy danych.

Jeżeli ktoś widzi tutaj jakieś rzeczy do poprawienia, albo możliwość usprawnienia kodu to bardzo chętnie posłucham, bo prawdę mówiąc innego rozwiązania nie znalazłem. Aczkolwiek jeżeli dobrze myślę to mój błąd leżał w złym podejściu do tematu. W funkcji "put" umieszczałem cały czas linki do zdjęcia, natomiast jak dobrze rozumiem powinienem umieścić sparsowane zdjęcie?

Obrazek po dodaniu poniżej:
screenshot-20210528003023.png

1

@Krispi One: Rzeczywiście, nie zwróciłem uwagi: put w dokumentacji Firebase przyjmuje blob jako dane, nie jako string.
edit: warto zwrócić uwagę na przyjmowane parametry: Blob | Uint8Array | ArrayBuffer

A u Ciebie rzeczywiście wrzucany jest string, czego nie zauważyłem, ale to dlatego, że moje doświadczenie z Firebase jest prawie żadne.

Dobrze, że udało Ci się to rozwiązać!
Możesz oznaczyć swój własny post jako rozwiązujący temat - będzie informacja, że problem rozwiązany.

1 użytkowników online, w tym zalogowanych: 0, gości: 1