Skip to content
Advertisement

Expo Camera Photo Upload To Firebase Storage is undefined – React Native

I am using import { Camera } from 'expo-camera'; to take pictures. The taken picture is stored in the devicecache. so far so good.

Now I am trying to upload this taken images to Google Firebase Storage using import { getStorage, ref, uploadBytes } from "firebase/storage";

The return of doing a photo is:

{ 
"width":5472,
"uri":"file:///data/user/0/host.exp.exponent/cache/ExperienceData/%2540g1sm0%252Feprojstant/Camera/3689f575-d849-4e3e-b4ea-1ba40b96cf02.jpg",
"height":7296
}

Now I try to upload this like that:

const storageRef = ref(storage, 'some-child');
const file = photo.uri 
        uploadBytes(storageRef, file).then((snapshot) => {
            console.log('Uploaded a blob or file!');
        });

After a little delay, there is a file created in firebase/storage . I can open this file by an texteditor. the file includes the text undefined

The assumption is that the uri that i hand over is not the right solution. However, I’m too new to development and can’t find any help for react native. do you have an idea, a link or an example? Do I first have to convert the file to a blob or base64 and if so, how?

Advertisement

Answer

Everytime after I post a Question, I do find the solution.

I blob the file like that:

const blob = await new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.onload = function () {
            resolve(xhr.response);
        };
        xhr.onerror = function (e) {
            console.log(e);
            reject(new TypeError("Network request failed"));
        };
        xhr.responseType = "blob";
        xhr.open("GET", uri, true);
        xhr.send(null);
    });

and uploaded this result like this:

uploadBytes(storageRef, blob).then((snapshot) => {
        console.log('Uploaded a blob or file!');
    });

Here is the full function for my solution:

const [hasPermission, setHasPermission] = useState(null);
const [type, setType] = useState(Camera.Constants.Type.back);
const [previewVisible, setPreviewVisible] = useState(false)
const [capturedImage, setCapturedImage] = useState(null)
let camera = Camera
const __takePicture = async () => {
    if (!camera) return
    const photo = await camera.takePictureAsync()
    setPreviewVisible(true)
    setCapturedImage(photo)

    // Create a root reference
    const storage = getStorage();
    const uri = photo.uri
    const blob = await new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.onload = function () {
            resolve(xhr.response);
        };
        xhr.onerror = function (e) {
            console.log(e);
            reject(new TypeError("Network request failed"));
        };
        xhr.responseType = "blob";
        xhr.open("GET", uri, true);
        xhr.send(null);
    });

        // TODO: UUID @some-child
        const storageRef = ref(storage, 'some-child');

        uploadBytes(storageRef, blob).then((snapshot) => {
            console.log('Uploaded a blob or file!');
        });
    }

useEffect(() => {
        (async () => {
            const { status } = await Camera.requestCameraPermissionsAsync();
            setHasPermission(status === 'granted');
        })();
    }, []);

if (hasPermission === null) {
        return <View />;
    }
    if (hasPermission === false) {
        return <Text>No access to camera</Text>;
    }
    return (YOUR VIEW RENDERING HERE)
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement