Skip to content

Cropped Images not loading in app #8405

@shortcipher3

Description

@shortcipher3

Operating System

Android 14/iOS 17

Browser Version

Chrome/Safari (webview)

Firebase SDK Version

firebase@10.12.4

Firebase SDK Product:

Auth, Storage

Describe your project's tooling

Next.js app is app webview

Describe the problem

Loading images from two buckets. When I load the images in my app with no modification they load fine from both buckets. However, I first want to crop the images, then load the cropped versions in the app. When I do this images from one of my buckets will load, but images from my other bucket will not.

It seems like signInWithCustomToken is hanging for the cropped version.

Steps and code to reproduce issue

Here is the non-cropped version

import React, { Component } from "react";
import styles from './thumbnail.module.css'
import { storage } from "../../../../utils/firebase";
import { getStorage, ref, getDownloadURL } from "firebase/storage";

export default class Thumbnail extends Component {
    constructor(props) {
        super(props);

        this.state = {
            croppedImg: "",
            imageUrl: "",
            imageError: "",
        };
    }
    componentDidMount(prevProps) {
        if (this.props.thumbnail.uri !== prevProps.thumbnail.uri) {
            const { uri, x_min, x_max, y_min, y_max, timestamp } = this.props.thumbnail;

            // Access Firebase Storage using the authenticated user
            const storageRef = ref(storage, uri)
            getDownloadURL(storageRef)
                .then((url) => {
                    this.setState({ imageUrl: url })
                })
                .catch((error) => {
                    this.setState({ imageError: error })
                    console.error("Error fetching thumbnail image URL:", error);
                });
        }
    }

    render() {
        const uri = this.props.thumbnail;
        return (
            <div>
                {this.state.imageUrl ? (
                    <>
                        {/* <textarea>{uri}</textarea>
                        <textarea>{this.state.imageUrl}</textarea>
                        <textarea>{this.state.imageError}</textarea> */}
                        <img
                            src={this.state.imageUrl}
                            alt="thumbnail"
                            className={styles.thumbnail}
                        />
                    </>
                ) : (
                    <div className="animate-pulse">
                        {/* no url
                        <textarea>{uri}</textarea>
                        <textarea>{this.state.imageError}</textarea> */}
                        <div className={styles.thumbnail}>
                            <div className="w-full h-full bg-gray-300 rounded mb-2"></div>
                        </div>
                    </div>
                )}
            </div>
        );
    }
}

The cropped version adds:

        getDownloadURL(storageRef)
            .then((url) => {
                this.setState({ imageUrl: url })
                // Create image object
                const img = new Image();
                img.crossOrigin = "anonymous";

                // Set up canvas element
                const canvas = document.createElement("canvas");
                const context = canvas.getContext("2d");

                // Wait for image to load
                img.onload = () => {
                    const x_diff = x_max - x_min;
                    const y_diff = y_max - y_min;

                    // Set the dimensions for the cropped image
                    const padding = 10;
                    let croppedWidth = null;
                    let croppedHeight = null;
                    let croppedXPadding = null;
                    let croppedYPadding = null;
                    if (x_diff > y_diff) {
                        croppedWidth = x_diff + padding;
                        croppedHeight = x_diff + padding;
                        croppedXPadding = 5;
                        croppedYPadding = (croppedHeight - y_diff) / 2;
                    } else {
                        croppedWidth = y_diff + padding;
                        croppedHeight = y_diff + padding;
                        croppedXPadding = (croppedWidth - x_diff) / 2;
                        croppedYPadding = 5;
                    }
                    // Set the position for the cropped image
                    let croppedX = x_min - croppedXPadding;
                    let croppedY = y_min - croppedYPadding;
                    // Add condition to handle edges
                    if (croppedX < 0) {
                        croppedX = 0;
                    }
                    if (croppedY < 0) {
                        croppedY = 0;
                    }
                    if (croppedX > img.width - croppedWidth) {
                        croppedX = img.width - croppedWidth;
                    }
                    if (croppedY > img.height - croppedHeight) {
                        croppedY = img.height - croppedHeight;
                    }

                    canvas.width = croppedWidth;
                    canvas.height = croppedHeight;

                    // Draw the cropped image onto the canvas element
                    context.drawImage(
                        img,
                        croppedX,
                        croppedY,
                        croppedWidth,
                        croppedHeight,
                        0,
                        0,
                        croppedWidth,
                        croppedHeight,
                    );

                    // Convert the cropped image on the canvas back to base64
                    const croppedBase64String = canvas.toDataURL();

                    // Update component state with the cropped image
                    this.setState({ croppedImg: croppedBase64String });
                };

                // Set the source of the image object to the URL obtained from Firebase Storage
                img.src = url;
            })
            .catch((error) => {
                this.setState({ imageError: error })

and

    render() {
        const uri = this.props.thumbnail;
        return (
            <div>
                {this.state.croppedImage ? (
                    <>
                        {/* <textarea>{uri}</textarea>
                        <textarea>{this.state.imageUrl}</textarea>
                        <textarea>{this.state.imageError}</textarea> */}
                        <img
                            src={this.state.croppedImage}
                            alt="thumbnail"
                            className={styles.thumbnail}
                        />
                    </>
                ) : (
                    <div className="animate-pulse">
                        {/* no url
                        <textarea>{uri}</textarea>
                        <textarea>{this.state.imageError}</textarea> */}
                        <div className={styles.thumbnail}>
                            <div className="w-full h-full bg-gray-300 rounded mb-2"></div>
                        </div>
                    </div>
                )}
            </div>
        );
    }
}

My signin code is like this:

            signInWithCustomToken(auth, token)
                .then((userCredential) => {
                    console.log(userCredential.user)
                })
                .catch((error) => {
                    console.error("Error code:", error.code);
                    console.error("Error message:", error.message);
                });

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions