-
Notifications
You must be signed in to change notification settings - Fork 986
Closed
Description
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);
});