Using OpenAI in my React app with Firebase. I see the image being processed in Firebase, but in the console I get an error

I receive the error in AutoDetailing.js when I submit a photo for capture.

Error uploading photo or analyzing image: Response is missing data field. AutoDetailing.js:37:20
Error details: FirebaseError: Response is missing data field.

But I receive the following in Firebase logs.

Received labels from OpenAI API: The image shows a young man in an indoor setting, holding up a green can towards the camera which has the text “Recycle Me” on it. He is smiling and wearing a light-colored t-shirt. The background appears to be a home interior with a neutral color tone. The focus is on promoting recycling based on the text visible on the can.

Here is my code below.

AutoDetailing.js

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>import React, { useState } from "react";
import Camera, { FACING_MODES } from 'react-html5-camera-photo';
import 'react-html5-camera-photo/build/css/index.css';
import PropTypes from 'prop-types';
import { useForm } from "react-hook-form";
import { storage, functions } from './firebase'; // Ensure the correct path
import { ref, uploadBytes, getDownloadURL } from 'firebase/storage';
import { httpsCallable } from 'firebase/functions';
function AutoCameraApp({ onClose, onPhotoCapture, formData }) {
const handlePhotoCapture = async (dataUri) => {
console.log('Photo captured:', dataUri);
const blob = await fetch(dataUri).then(res => res.blob());
const storageRef = ref(storage, `vehicle-photos/${Date.now()}-vehicle-photo.png`);
try {
const snapshot = await uploadBytes(storageRef, blob);
console.log('Uploaded the file!', snapshot);
const downloadUrl = await getDownloadURL(snapshot.ref);
console.log('File available at', downloadUrl);
const analyzeImage = httpsCallable(functions, 'analyzeImage');
const payload = { imageUrl: downloadUrl };
console.log('Calling analyzeImage with payload:', payload);
const result = await analyzeImage(payload);
console.log('Result from analyzeImage:', result);
if (result.data && result.data.labels) {
onPhotoCapture(downloadUrl, result.data.labels);
} else {
console.error('Response is missing labels field:', result.data);
}
} catch (error) {
console.error('Error uploading photo or analyzing image:', error.message);
console.error('Error details:', error);
}
console.log('Form Data:', formData);
};
return (
<div className="camera-fullscreen">
<div className="camera-header">
Take a picture of your vehicle
</div>
<Camera
onTakePhoto={(dataUri) => { handlePhotoCapture(dataUri); }}
isFullscreen={true}
idealFacingMode={FACING_MODES.ENVIRONMENT}
isMaxResolution={true}
/>
<button onClick={onClose}>Close</button>
</div>
);
AutoCameraApp.propTypes = {
onClose: PropTypes.func.isRequired,
onPhotoCapture: PropTypes.func.isRequired,
formData: PropTypes.object
};
const AutoDetailing = ({ vehicleTypes, pricingMatrix, setCurrentVehicle }) => {
const { register, handleSubmit, watch, formState: { errors }, getValues } = useForm();
const [selectedVehicle, setSelectedVehicle] = useState(null);
const [showCamera, setShowCamera] = useState(false);
const [photoData, setPhotoData] = useState(null);
const [analysisResult, setAnalysisResult] = useState(null);
const [isFormVisible, setIsFormVisible] = useState(false);
const onSubmit = data => {
console.log('Form submitted:', data);
// Handle form submission here
};
const handleVehicleSelect = (vehicleType) => {
setSelectedVehicle(vehicleType);
console.log('Vehicle selected:', vehicleType);
};
const handlePackageSelect = (packageType) => {
setCurrentVehicle(selectedVehicle);
setShowCamera(false);
setIsFormVisible(true);
console.log('Package selected:', packageType);
};
const handleCloseCamera = () => {
setShowCamera(false);
setIsFormVisible(false);
console.log('Camera closed');
};
const handlePhotoCapture = (downloadUrl, analysis) => {
setPhotoData(downloadUrl);
setAnalysisResult(analysis);
setShowCamera(false);
setIsFormVisible(false);
console.log('Photo captured and analyzed:', { downloadUrl, analysis });
};
const watchFields = watch(["firstName", "lastName", "threeAvailDatesTimes", "address"]);
const isFormComplete = watchFields.every(field => field && field.trim() !== "");
const formData = getValues();
return (
<div className="service-detail-wrapper">
<p className="service-description">
We're deeply committed to the art of automotive detailing, ensuring no detail is overlooked in our meticulous process. Our approach combines safe solutions with expert care to maintain the highest quality standards, preserving your vehicle's finish impeccably. Did you know that most swirls on vehicles stem from improper hand washing or automatic car washes? We offer various detailing packages tailored to your needs, with our standard package recommended biannually and the full package annually. You can also customize your package to suit your preferences. Rest assured, our dedication to customer satisfaction means we'll promptly address any concerns to ensure your experience with us is exceptional.
</p>
{isFormVisible ? (
<div className="booking-overlay">
<form className="fullscreen-form" onSubmit={handleSubmit(onSubmit)}>
<h3>Fill out the following form</h3>
<div className="input-fields">
<input type="text" placeholder="First Name" {...register("firstName", { required: true })} />
{errors.firstName && <span>This field is required</span>}
<input type="text" placeholder="Last Name" {...register("lastName", { required: true })} />
{errors.lastName && <span>This field is required</span>}
<input type="tel" placeholder="Phone" {...register("phone", { required: true })} />
{errors.phone && <span>This field is required</span>}
<input type="email" placeholder="Email" {...register("email", { required: true })} />
{errors.email && <span>This field is required</span>}
<input type="text" placeholder="3 Available Dates / Times" {...register("threeAvailDatesTimes", { required: true })} />
{errors.threeAvailDatesTimes && <span>This field is required</span>}
<input type="text" placeholder="Address" {...register("address", { required: true })} />
{errors.address && <span>This field is required</span>}
<button type="button" onClick={() => setShowCamera(true)} className="view-packages" disabled={!isFormComplete}>Proceed to vehicle capture</button>
</div>
</form>
</div>
) : (
<div>
<h3>Select a Vehicle</h3>
<div className="vehicle-buttons">
{vehicleTypes.map((vehicleType, index) => (
<button key={index} className="view-packages" onClick={() => handleVehicleSelect(vehicleType)}>
{vehicleType}
</button>
))}
</div>
{selectedVehicle && pricingMatrix[selectedVehicle] && (
<div className="pricing-matrix">
<h3>Select a Package</h3>
<div className="package">
<h4>Basic Package</h4>
<p className="service-description">{pricingMatrix[selectedVehicle].basicDescription}</p>
<p className="service-cost">Price: ${pricingMatrix[selectedVehicle].basic}</p>
<button onClick={() => handlePackageSelect('basic')} className="view-packages">Book Now</button>
</div>
<div className="package">
<h4>Standard Package</h4>
<p className="service-description">{pricingMatrix[selectedVehicle].standardDescription}</p>
<p className="service-cost">Price: ${pricingMatrix[selectedVehicle].standard}</p>
<button onClick={() => handlePackageSelect('standard')} className="view-packages">Book Now</button>
</div>
<div className="package">
<h4>Full Package</h4>
<p className="service-description">{pricingMatrix[selectedVehicle].fullDescription}</p>
<p className="service-cost">Price: ${pricingMatrix[selectedVehicle].full}</p>
<button onClick={() => handlePackageSelect('full')} className="view-packages">Book Now</button>
</div>
</div>
)}
</div>
)}
{showCamera && <AutoCameraApp onClose={handleCloseCamera} onPhotoCapture={handlePhotoCapture} formData={formData} />}
<div className="faqs">
<h3 className="faq-header">Frequently Asked Questions</h3>
<div className="faq">
<h4>How do you ensure safe detailing of exterior surfaces?</h4>
<p>To ensure safe detailing of exterior surfaces, we use a three-bucket method along with new towels for each detail. Our wheel brushes are soft, cleaned after each use, and inspected for damage. The method includes soap, rinse, and wheel buckets, each with a grit guard to catch contaminants. We then go over the vehicle's panels after rinsing them off.</p>
</div>
<div className="faq">
<h4>How can I trust the interior detailing to be immaculate?</h4>
<p>We understand the importance of interior detailing and use specialized tools such as steam cleaners, heated carpet extractors, ozone generators, specialized chemicals, and detailing brushes. Rest assured, we have all the necessary equipment and expertise to deliver exceptional interior detailing.</p>
</div>
<div className="faq">
<h4>How often should I detail my car to keep it looking new?</h4>
<p>The frequency depends on your preferences and budget. For minimal effort and year-round pristine condition, we recommend a ceramic coating package. Otherwise, we suggest a full detail annually, a standard detail biannually, and a basic detail as needed. Note that foregoing ceramic coating may result in higher long-term costs.</p>
</div>
</div>
</div>
);
};
export default AutoDetailing;
</code>
<code>import React, { useState } from "react"; import Camera, { FACING_MODES } from 'react-html5-camera-photo'; import 'react-html5-camera-photo/build/css/index.css'; import PropTypes from 'prop-types'; import { useForm } from "react-hook-form"; import { storage, functions } from './firebase'; // Ensure the correct path import { ref, uploadBytes, getDownloadURL } from 'firebase/storage'; import { httpsCallable } from 'firebase/functions'; function AutoCameraApp({ onClose, onPhotoCapture, formData }) { const handlePhotoCapture = async (dataUri) => { console.log('Photo captured:', dataUri); const blob = await fetch(dataUri).then(res => res.blob()); const storageRef = ref(storage, `vehicle-photos/${Date.now()}-vehicle-photo.png`); try { const snapshot = await uploadBytes(storageRef, blob); console.log('Uploaded the file!', snapshot); const downloadUrl = await getDownloadURL(snapshot.ref); console.log('File available at', downloadUrl); const analyzeImage = httpsCallable(functions, 'analyzeImage'); const payload = { imageUrl: downloadUrl }; console.log('Calling analyzeImage with payload:', payload); const result = await analyzeImage(payload); console.log('Result from analyzeImage:', result); if (result.data && result.data.labels) { onPhotoCapture(downloadUrl, result.data.labels); } else { console.error('Response is missing labels field:', result.data); } } catch (error) { console.error('Error uploading photo or analyzing image:', error.message); console.error('Error details:', error); } console.log('Form Data:', formData); }; return ( <div className="camera-fullscreen"> <div className="camera-header"> Take a picture of your vehicle </div> <Camera onTakePhoto={(dataUri) => { handlePhotoCapture(dataUri); }} isFullscreen={true} idealFacingMode={FACING_MODES.ENVIRONMENT} isMaxResolution={true} /> <button onClick={onClose}>Close</button> </div> ); AutoCameraApp.propTypes = { onClose: PropTypes.func.isRequired, onPhotoCapture: PropTypes.func.isRequired, formData: PropTypes.object }; const AutoDetailing = ({ vehicleTypes, pricingMatrix, setCurrentVehicle }) => { const { register, handleSubmit, watch, formState: { errors }, getValues } = useForm(); const [selectedVehicle, setSelectedVehicle] = useState(null); const [showCamera, setShowCamera] = useState(false); const [photoData, setPhotoData] = useState(null); const [analysisResult, setAnalysisResult] = useState(null); const [isFormVisible, setIsFormVisible] = useState(false); const onSubmit = data => { console.log('Form submitted:', data); // Handle form submission here }; const handleVehicleSelect = (vehicleType) => { setSelectedVehicle(vehicleType); console.log('Vehicle selected:', vehicleType); }; const handlePackageSelect = (packageType) => { setCurrentVehicle(selectedVehicle); setShowCamera(false); setIsFormVisible(true); console.log('Package selected:', packageType); }; const handleCloseCamera = () => { setShowCamera(false); setIsFormVisible(false); console.log('Camera closed'); }; const handlePhotoCapture = (downloadUrl, analysis) => { setPhotoData(downloadUrl); setAnalysisResult(analysis); setShowCamera(false); setIsFormVisible(false); console.log('Photo captured and analyzed:', { downloadUrl, analysis }); }; const watchFields = watch(["firstName", "lastName", "threeAvailDatesTimes", "address"]); const isFormComplete = watchFields.every(field => field && field.trim() !== ""); const formData = getValues(); return ( <div className="service-detail-wrapper"> <p className="service-description"> We're deeply committed to the art of automotive detailing, ensuring no detail is overlooked in our meticulous process. Our approach combines safe solutions with expert care to maintain the highest quality standards, preserving your vehicle's finish impeccably. Did you know that most swirls on vehicles stem from improper hand washing or automatic car washes? We offer various detailing packages tailored to your needs, with our standard package recommended biannually and the full package annually. You can also customize your package to suit your preferences. Rest assured, our dedication to customer satisfaction means we'll promptly address any concerns to ensure your experience with us is exceptional. </p> {isFormVisible ? ( <div className="booking-overlay"> <form className="fullscreen-form" onSubmit={handleSubmit(onSubmit)}> <h3>Fill out the following form</h3> <div className="input-fields"> <input type="text" placeholder="First Name" {...register("firstName", { required: true })} /> {errors.firstName && <span>This field is required</span>} <input type="text" placeholder="Last Name" {...register("lastName", { required: true })} /> {errors.lastName && <span>This field is required</span>} <input type="tel" placeholder="Phone" {...register("phone", { required: true })} /> {errors.phone && <span>This field is required</span>} <input type="email" placeholder="Email" {...register("email", { required: true })} /> {errors.email && <span>This field is required</span>} <input type="text" placeholder="3 Available Dates / Times" {...register("threeAvailDatesTimes", { required: true })} /> {errors.threeAvailDatesTimes && <span>This field is required</span>} <input type="text" placeholder="Address" {...register("address", { required: true })} /> {errors.address && <span>This field is required</span>} <button type="button" onClick={() => setShowCamera(true)} className="view-packages" disabled={!isFormComplete}>Proceed to vehicle capture</button> </div> </form> </div> ) : ( <div> <h3>Select a Vehicle</h3> <div className="vehicle-buttons"> {vehicleTypes.map((vehicleType, index) => ( <button key={index} className="view-packages" onClick={() => handleVehicleSelect(vehicleType)}> {vehicleType} </button> ))} </div> {selectedVehicle && pricingMatrix[selectedVehicle] && ( <div className="pricing-matrix"> <h3>Select a Package</h3> <div className="package"> <h4>Basic Package</h4> <p className="service-description">{pricingMatrix[selectedVehicle].basicDescription}</p> <p className="service-cost">Price: ${pricingMatrix[selectedVehicle].basic}</p> <button onClick={() => handlePackageSelect('basic')} className="view-packages">Book Now</button> </div> <div className="package"> <h4>Standard Package</h4> <p className="service-description">{pricingMatrix[selectedVehicle].standardDescription}</p> <p className="service-cost">Price: ${pricingMatrix[selectedVehicle].standard}</p> <button onClick={() => handlePackageSelect('standard')} className="view-packages">Book Now</button> </div> <div className="package"> <h4>Full Package</h4> <p className="service-description">{pricingMatrix[selectedVehicle].fullDescription}</p> <p className="service-cost">Price: ${pricingMatrix[selectedVehicle].full}</p> <button onClick={() => handlePackageSelect('full')} className="view-packages">Book Now</button> </div> </div> )} </div> )} {showCamera && <AutoCameraApp onClose={handleCloseCamera} onPhotoCapture={handlePhotoCapture} formData={formData} />} <div className="faqs"> <h3 className="faq-header">Frequently Asked Questions</h3> <div className="faq"> <h4>How do you ensure safe detailing of exterior surfaces?</h4> <p>To ensure safe detailing of exterior surfaces, we use a three-bucket method along with new towels for each detail. Our wheel brushes are soft, cleaned after each use, and inspected for damage. The method includes soap, rinse, and wheel buckets, each with a grit guard to catch contaminants. We then go over the vehicle's panels after rinsing them off.</p> </div> <div className="faq"> <h4>How can I trust the interior detailing to be immaculate?</h4> <p>We understand the importance of interior detailing and use specialized tools such as steam cleaners, heated carpet extractors, ozone generators, specialized chemicals, and detailing brushes. Rest assured, we have all the necessary equipment and expertise to deliver exceptional interior detailing.</p> </div> <div className="faq"> <h4>How often should I detail my car to keep it looking new?</h4> <p>The frequency depends on your preferences and budget. For minimal effort and year-round pristine condition, we recommend a ceramic coating package. Otherwise, we suggest a full detail annually, a standard detail biannually, and a basic detail as needed. Note that foregoing ceramic coating may result in higher long-term costs.</p> </div> </div> </div> ); }; export default AutoDetailing; </code>
import React, { useState } from "react";
import Camera, { FACING_MODES } from 'react-html5-camera-photo';
import 'react-html5-camera-photo/build/css/index.css';
import PropTypes from 'prop-types';
import { useForm } from "react-hook-form";
import { storage, functions } from './firebase'; // Ensure the correct path
import { ref, uploadBytes, getDownloadURL } from 'firebase/storage';
import { httpsCallable } from 'firebase/functions';

function AutoCameraApp({ onClose, onPhotoCapture, formData }) {
    const handlePhotoCapture = async (dataUri) => {
        console.log('Photo captured:', dataUri);
        const blob = await fetch(dataUri).then(res => res.blob());
        const storageRef = ref(storage, `vehicle-photos/${Date.now()}-vehicle-photo.png`);

        try {
            const snapshot = await uploadBytes(storageRef, blob);
            console.log('Uploaded the file!', snapshot);

            const downloadUrl = await getDownloadURL(snapshot.ref);
            console.log('File available at', downloadUrl);

            const analyzeImage = httpsCallable(functions, 'analyzeImage');
            const payload = { imageUrl: downloadUrl };
            console.log('Calling analyzeImage with payload:', payload);

            const result = await analyzeImage(payload);
            console.log('Result from analyzeImage:', result);

            if (result.data && result.data.labels) {
                onPhotoCapture(downloadUrl, result.data.labels);
            } else {
                console.error('Response is missing labels field:', result.data);
            }
        } catch (error) {
            console.error('Error uploading photo or analyzing image:', error.message);
            console.error('Error details:', error);
        }
        console.log('Form Data:', formData);
    };

    return (
        <div className="camera-fullscreen">
            <div className="camera-header">
                Take a picture of your vehicle
            </div>
            <Camera
                onTakePhoto={(dataUri) => { handlePhotoCapture(dataUri); }}
                isFullscreen={true}
                idealFacingMode={FACING_MODES.ENVIRONMENT}
                isMaxResolution={true}
            />
            <button onClick={onClose}>Close</button>
        </div>
    );

AutoCameraApp.propTypes = {
    onClose: PropTypes.func.isRequired,
    onPhotoCapture: PropTypes.func.isRequired,
    formData: PropTypes.object
};

const AutoDetailing = ({ vehicleTypes, pricingMatrix, setCurrentVehicle }) => {
    const { register, handleSubmit, watch, formState: { errors }, getValues } = useForm();
    const [selectedVehicle, setSelectedVehicle] = useState(null);
    const [showCamera, setShowCamera] = useState(false);
    const [photoData, setPhotoData] = useState(null);
    const [analysisResult, setAnalysisResult] = useState(null);
    const [isFormVisible, setIsFormVisible] = useState(false);

    const onSubmit = data => {
        console.log('Form submitted:', data);
        // Handle form submission here
    };

    const handleVehicleSelect = (vehicleType) => {
        setSelectedVehicle(vehicleType);
        console.log('Vehicle selected:', vehicleType);
    };

    const handlePackageSelect = (packageType) => {
        setCurrentVehicle(selectedVehicle);
        setShowCamera(false);
        setIsFormVisible(true);
        console.log('Package selected:', packageType);
    };

    const handleCloseCamera = () => {
        setShowCamera(false);
        setIsFormVisible(false);
        console.log('Camera closed');
    };

    const handlePhotoCapture = (downloadUrl, analysis) => {
        setPhotoData(downloadUrl);
        setAnalysisResult(analysis);
        setShowCamera(false);
        setIsFormVisible(false);
        console.log('Photo captured and analyzed:', { downloadUrl, analysis });
    };

    const watchFields = watch(["firstName", "lastName", "threeAvailDatesTimes", "address"]);
    const isFormComplete = watchFields.every(field => field && field.trim() !== "");

    const formData = getValues();

    return (
        <div className="service-detail-wrapper">
            <p className="service-description">
                We're deeply committed to the art of automotive detailing, ensuring no detail is overlooked in our meticulous process. Our approach combines safe solutions with expert care to maintain the highest quality standards, preserving your vehicle's finish impeccably. Did you know that most swirls on vehicles stem from improper hand washing or automatic car washes? We offer various detailing packages tailored to your needs, with our standard package recommended biannually and the full package annually. You can also customize your package to suit your preferences. Rest assured, our dedication to customer satisfaction means we'll promptly address any concerns to ensure your experience with us is exceptional.
            </p>
            {isFormVisible ? (
                <div className="booking-overlay">
                    <form className="fullscreen-form" onSubmit={handleSubmit(onSubmit)}>
                        <h3>Fill out the following form</h3>
                        <div className="input-fields">
                            <input type="text" placeholder="First Name" {...register("firstName", { required: true })} />
                            {errors.firstName && <span>This field is required</span>}

                            <input type="text" placeholder="Last Name" {...register("lastName", { required: true })} />
                            {errors.lastName && <span>This field is required</span>}

                            <input type="tel" placeholder="Phone" {...register("phone", { required: true })} />
                            {errors.phone && <span>This field is required</span>}

                            <input type="email" placeholder="Email" {...register("email", { required: true })} />
                            {errors.email && <span>This field is required</span>}

                            <input type="text" placeholder="3 Available Dates / Times" {...register("threeAvailDatesTimes", { required: true })} />
                            {errors.threeAvailDatesTimes && <span>This field is required</span>}

                            <input type="text" placeholder="Address" {...register("address", { required: true })} />
                            {errors.address && <span>This field is required</span>}

                            <button type="button" onClick={() => setShowCamera(true)} className="view-packages" disabled={!isFormComplete}>Proceed to vehicle capture</button>
                        </div>
                    </form>
                </div>
            ) : (
                <div>
                    <h3>Select a Vehicle</h3>
                    <div className="vehicle-buttons">
                        {vehicleTypes.map((vehicleType, index) => (
                            <button key={index} className="view-packages" onClick={() => handleVehicleSelect(vehicleType)}>
                                {vehicleType}
                            </button>
                        ))}
                    </div>
                    {selectedVehicle && pricingMatrix[selectedVehicle] && (
                        <div className="pricing-matrix">
                            <h3>Select a Package</h3>
                            <div className="package">
                                <h4>Basic Package</h4>
                                <p className="service-description">{pricingMatrix[selectedVehicle].basicDescription}</p>
                                <p className="service-cost">Price: ${pricingMatrix[selectedVehicle].basic}</p>
                                <button onClick={() => handlePackageSelect('basic')} className="view-packages">Book Now</button>
                            </div>
                            <div className="package">
                                <h4>Standard Package</h4>
                                <p className="service-description">{pricingMatrix[selectedVehicle].standardDescription}</p>
                                <p className="service-cost">Price: ${pricingMatrix[selectedVehicle].standard}</p>
                                <button onClick={() => handlePackageSelect('standard')} className="view-packages">Book Now</button>
                            </div>
                            <div className="package">
                                <h4>Full Package</h4>
                                <p className="service-description">{pricingMatrix[selectedVehicle].fullDescription}</p>
                                <p className="service-cost">Price: ${pricingMatrix[selectedVehicle].full}</p>
                                <button onClick={() => handlePackageSelect('full')} className="view-packages">Book Now</button>
                            </div>
                        </div>
                    )}
                </div>
            )}
            {showCamera && <AutoCameraApp onClose={handleCloseCamera} onPhotoCapture={handlePhotoCapture} formData={formData} />}
            <div className="faqs">
                <h3 className="faq-header">Frequently Asked Questions</h3>
                <div className="faq">
                    <h4>How do you ensure safe detailing of exterior surfaces?</h4>
                    <p>To ensure safe detailing of exterior surfaces, we use a three-bucket method along with new towels for each detail. Our wheel brushes are soft, cleaned after each use, and inspected for damage. The method includes soap, rinse, and wheel buckets, each with a grit guard to catch contaminants. We then go over the vehicle's panels after rinsing them off.</p>
                </div>
                <div className="faq">
                    <h4>How can I trust the interior detailing to be immaculate?</h4>
                    <p>We understand the importance of interior detailing and use specialized tools such as steam cleaners, heated carpet extractors, ozone generators, specialized chemicals, and detailing brushes. Rest assured, we have all the necessary equipment and expertise to deliver exceptional interior detailing.</p>
                </div>
                <div className="faq">
                    <h4>How often should I detail my car to keep it looking new?</h4>
                    <p>The frequency depends on your preferences and budget. For minimal effort and year-round pristine condition, we recommend a ceramic coating package. Otherwise, we suggest a full detail annually, a standard detail biannually, and a basic detail as needed. Note that foregoing ceramic coating may result in higher long-term costs.</p>
                </div>
            </div>
        </div>
    );
};

export default AutoDetailing;

index.js

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>const functions = require("firebase-functions");
const cors = require("cors")({ origin: true });
const admin = require("firebase-admin");
const OpenAI = require("openai");
admin.initializeApp();
const openai = new OpenAI({
apiKey: 'REDACTED', // Replace this with your actual OpenAI API key
});
exports.analyzeImage = functions.https.onRequest((req, res) => {
res.set("Access-Control-Allow-Origin", "*");
res.set("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
res.set("Access-Control-Allow-Headers", "Content-Type, Authorization");
if (req.method === "OPTIONS") {
res.status(204).send("");
return;
}
cors(req, res, async () => {
console.log("Request received:", req.body);
const imageUrl = req.body.imageUrl || (req.body.data && req.body.data.imageUrl);
console.log("Received imageUrl:", imageUrl);
if (!imageUrl) {
console.error("Missing imageUrl");
return res.status(400).send("Missing imageUrl");
}
try {
const messages = [
{
role: "user",
content: [
{ type: "text", text: "What’s in this image?" },
{ type: "image_url", image_url: { url: imageUrl } },
],
},
];
console.log("Messages payload:", JSON.stringify(messages, null, 2));
const openaiResponse = await openai.chat.completions.create({
model: "gpt-4-turbo", // Adjust the model as needed
messages: messages,
max_tokens: 300,
});
console.log("OpenAI API response:", JSON.stringify(openaiResponse, null, 2));
if (openaiResponse.choices && openaiResponse.choices.length > 0) {
const labels = openaiResponse.choices[0].message.content;
console.log("Received labels from OpenAI API:", labels);
res.status(200).json({ labels }); // Ensure to send a JSON response
} else {
throw new Error("Invalid response structure");
}
} catch (error) {
console.error("Error analyzing image:", error.message);
if (error.response) {
console.error("Error response data:", JSON.stringify(error.response.data, null, 2));
}
res.status(500).send("Internal Server Error");
}
});
});
</code>
<code>const functions = require("firebase-functions"); const cors = require("cors")({ origin: true }); const admin = require("firebase-admin"); const OpenAI = require("openai"); admin.initializeApp(); const openai = new OpenAI({ apiKey: 'REDACTED', // Replace this with your actual OpenAI API key }); exports.analyzeImage = functions.https.onRequest((req, res) => { res.set("Access-Control-Allow-Origin", "*"); res.set("Access-Control-Allow-Methods", "GET, POST, OPTIONS"); res.set("Access-Control-Allow-Headers", "Content-Type, Authorization"); if (req.method === "OPTIONS") { res.status(204).send(""); return; } cors(req, res, async () => { console.log("Request received:", req.body); const imageUrl = req.body.imageUrl || (req.body.data && req.body.data.imageUrl); console.log("Received imageUrl:", imageUrl); if (!imageUrl) { console.error("Missing imageUrl"); return res.status(400).send("Missing imageUrl"); } try { const messages = [ { role: "user", content: [ { type: "text", text: "What’s in this image?" }, { type: "image_url", image_url: { url: imageUrl } }, ], }, ]; console.log("Messages payload:", JSON.stringify(messages, null, 2)); const openaiResponse = await openai.chat.completions.create({ model: "gpt-4-turbo", // Adjust the model as needed messages: messages, max_tokens: 300, }); console.log("OpenAI API response:", JSON.stringify(openaiResponse, null, 2)); if (openaiResponse.choices && openaiResponse.choices.length > 0) { const labels = openaiResponse.choices[0].message.content; console.log("Received labels from OpenAI API:", labels); res.status(200).json({ labels }); // Ensure to send a JSON response } else { throw new Error("Invalid response structure"); } } catch (error) { console.error("Error analyzing image:", error.message); if (error.response) { console.error("Error response data:", JSON.stringify(error.response.data, null, 2)); } res.status(500).send("Internal Server Error"); } }); }); </code>
const functions = require("firebase-functions");
const cors = require("cors")({ origin: true });
const admin = require("firebase-admin");
const OpenAI = require("openai");

admin.initializeApp();

const openai = new OpenAI({
    apiKey: 'REDACTED', // Replace this with your actual OpenAI API key
});

exports.analyzeImage = functions.https.onRequest((req, res) => {
    res.set("Access-Control-Allow-Origin", "*");
    res.set("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
    res.set("Access-Control-Allow-Headers", "Content-Type, Authorization");

    if (req.method === "OPTIONS") {
        res.status(204).send("");
        return;
    }

    cors(req, res, async () => {
        console.log("Request received:", req.body);

        const imageUrl = req.body.imageUrl || (req.body.data && req.body.data.imageUrl);
        console.log("Received imageUrl:", imageUrl);

        if (!imageUrl) {
            console.error("Missing imageUrl");
            return res.status(400).send("Missing imageUrl");
        }

        try {
            const messages = [
                {
                    role: "user",
                    content: [
                        { type: "text", text: "What’s in this image?" },
                        { type: "image_url", image_url: { url: imageUrl } },
                    ],
                },
            ];

            console.log("Messages payload:", JSON.stringify(messages, null, 2));

            const openaiResponse = await openai.chat.completions.create({
                model: "gpt-4-turbo", // Adjust the model as needed
                messages: messages,
                max_tokens: 300,
            });

            console.log("OpenAI API response:", JSON.stringify(openaiResponse, null, 2));

            if (openaiResponse.choices && openaiResponse.choices.length > 0) {
                const labels = openaiResponse.choices[0].message.content;
                console.log("Received labels from OpenAI API:", labels);
                res.status(200).json({ labels }); // Ensure to send a JSON response
            } else {
                throw new Error("Invalid response structure");
            }
        } catch (error) {
            console.error("Error analyzing image:", error.message);
            if (error.response) {
                console.error("Error response data:", JSON.stringify(error.response.data, null, 2));
            }
            res.status(500).send("Internal Server Error");
        }
    });
});

firebase.js

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>const firebase = require('firebase/app');
require('firebase/firestore');
require('firebase/storage');
const firebaseConfig = {
apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.REACT_APP_FIREBASE_APP_ID,
measurementId: process.env.REACT_APP_FIREBASE_MEASUREMENT_ID,
};
firebase.initializeApp(firebaseConfig);
const db = firebase.firestore();
const storage = firebase.storage();
module.exports = { db, storage };
</code>
<code>const firebase = require('firebase/app'); require('firebase/firestore'); require('firebase/storage'); const firebaseConfig = { apiKey: process.env.REACT_APP_FIREBASE_API_KEY, authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN, projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID, storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET, messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID, appId: process.env.REACT_APP_FIREBASE_APP_ID, measurementId: process.env.REACT_APP_FIREBASE_MEASUREMENT_ID, }; firebase.initializeApp(firebaseConfig); const db = firebase.firestore(); const storage = firebase.storage(); module.exports = { db, storage }; </code>
const firebase = require('firebase/app');
require('firebase/firestore');
require('firebase/storage');

const firebaseConfig = {
  apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
  authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
  projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
  storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID,
  appId: process.env.REACT_APP_FIREBASE_APP_ID,
  measurementId: process.env.REACT_APP_FIREBASE_MEASUREMENT_ID,
};

firebase.initializeApp(firebaseConfig);

const db = firebase.firestore();
const storage = firebase.storage();

module.exports = { db, storage };

I’ve tried using base64 to pass through images and that failed, I’m getting a response with image url in Firebase but not in console.

New contributor

Johnathon Nguyen is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật