Image Not Returning Debug

User
import { db, storage } from '@/firebase'
import {
collection,
addDoc,
getDocs,
doc,
deleteDoc,
updateDoc,
} from 'firebase/firestore'
import {
ref as storageRef,
uploadBytes,
getDownloadURL,
deleteObject,
} from 'firebase/storage'

const portfolioCollection = collection(db, 'portfolio');

export const addPortfolioItem = async ({ title, description, url, imageFile}: { title:string, description:string, url:string, imageFile:File}) => {
try {
const imgPath = `portfolio/${Date.now()}_${imageFile.name}`
const imgRef = storageRef(storage, imgPath)

await uploadBytes(imgRef, imageFile)
const imageUrl = await getDownloadURL(imgRef)

const docRef = await addDoc(portfolioCollection, {
title,
description,
url,
image: imageUrl,
imagePath: imgPath,
createdAt: new Date(),
// Store for deletion later if needed
})

return docRef.id
} catch (error) {
console.error('Error adding portfolio item:', error)
throw error
}
}

export const fetchPortfolioItems = async () => {
try {
const snapshot = await getDocs(portfolioCollection)
return snapshot.docs.map(doc => ({
id: doc.id,
…doc.data(),
}))
} catch (error) {
console.error('Error fetching portfolio items:', error)
return []
}
}
image not returning

Assistant
If you're getting portfolio items but the `image` field is `undefined` or not returning as expected, here are a few things to check:

### ✅ 1. **Check Firestore Data Structure**

In Firestore, verify that the `image` field **actually exists** in each document under the `portfolio` collection.

– Go to [Firebase Console](https://console.firebase.google.com/)
– Navigate to **Firestore Database**
– Open your `portfolio` collection
– Confirm that each document contains the field `image` with a valid URL

### ✅ 2. **Ensure Firestore Rules Allow Reads**

Your Firestore security rules should allow reads on the `portfolio` collection for the current user or environment:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /portfolio/{document=**} {
      allow read, write: if true; // or add proper auth checks
    }
  }
}

### ✅ 3. **Ensure the Correct Export Format**

In your `fetchPortfolioItems`, make sure `doc.data()` returns the correct object.

You're doing this:

return snapshot.docs.map(doc => ({
  id: doc.id,
  ...doc.data(),
}))

Which is correct.

To debug, log each item:

const items = snapshot.docs.map(doc => ({
  id: doc.id,
  ...doc.data(),
}));

console.log('Fetched items:', items);

return items;

Check the console to see if `image` is present.

### ✅ 4. **Check Firestore Timestamp Conversion**

Sometimes `createdAt` as a `Date` object causes serialization issues. You can use `Timestamp`:

import { Timestamp } from 'firebase/firestore'

await addDoc(portfolioCollection, {
  title,
  description,
  url,
  image: imageUrl,
  imagePath: imgPath,
  createdAt: Timestamp.now(),
})

### ✅ 5. **Accessing in UI (Frontend)**

If you're rendering the image in Vue or React, make sure the property is being accessed correctly:

<img :src="item.image" alt="Portfolio image" />

### ✅ 6. **Check Firebase Storage Rules**

Also, confirm that your storage rules allow downloading images:

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /portfolio/{allPaths=**} {
      allow read, write: if true; // replace with proper auth logic
    }
  }
}

If all the above checks out and you're still not getting the image, let me know what your console output is when logging the fetched data — I can help debug further from there.

User
Yes firebase database include the imageurl
Assistant
Great — if the Firebase database includes the `image` URL but you're not seeing it in your app, then we can narrow the issue down to one of the following:

### 🔍 Let's walk through a quick checklist:

#### ✅ 1. **Log the fetched data**
In your component or wherever you're calling `fetchPortfolioItems`, log the response:

const items = await fetchPortfolioItems();
console.log('Fetched portfolio items:', items);

> Check if `image` appears in the log for each item.

#### ✅ 2. **Inspect a single item**
Double-check by logging just one item:

console.log('First item:', items[0]);

If the image URL is there in the log but not appearing in the UI, it's likely a rendering issue.

#### ✅ 3. **Check how you're rendering the image in the UI**

For Vue:

<img :src="item.image" alt="Portfolio Image" />

For React:

<img src={item.image} alt="Portfolio Image" />

> Also inspect the element in dev tools — make sure the `src` is correctly applied, and not broken or 403/404.

#### ✅ 4. **Broken image URLs?**
Visit the image URL manually in a browser. If it gives a `403` or `not found`, it could be a Firebase Storage permissions issue.

Update storage rules (temporarily for testing):

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /portfolio/{allPaths=**} {
      allow read: if true;
      allow write: if request.auth != null;
    }
  }
}

#### ✅ 5. **Recheck `addDoc` image field**

From your code, it looks correct:

const docRef = await addDoc(portfolioCollection, {
  title,
  description,
  url,
  image: imageUrl, // 👈 this should work
  imagePath: imgPath,
  createdAt: new Date(),
});

You might want to **re-add** an item and confirm that the new image also doesn't show.

If all of this checks out and it’s *still* not rendering — could you share how you're rendering the portfolio items in your frontend (Vue, React, etc.)? That might help pinpoint it.

User
Type '{ id: string; }[]' is not assignable to type 'never[]'.
Type '{ id: string; }' is not assignable to type 'never'
const portfolioItems = ref([])
const loadItems = async () => {
portfolioItems.value = await fetchPortfolioItems();
console.log(portfolioItems.value);
}
Assistant
Ah yes — this TypeScript error is caused by the fact that `ref([])` by default infers the type as `Ref`, so when you try to assign an array of `{ id: string; … }`, it throws an error.

### ✅ Solution: Give your `ref` a proper type

You can fix it by explicitly typing the items:

#### Option 1: Inline type

const portfolioItems = ref<{ id: string; title: string; description: string; url: string; image: string; imagePath: string; createdAt: any }[]>([])

If you already know the structure, this works fine.

#### Option 2: Define a reusable type or interface

interface PortfolioItem {
  id: string;
  title: string;
  description: string;
  url: string;
  image: string;
  imagePath: string;
  createdAt: any;
}

const portfolioItems = ref<PortfolioItem[]>([])

This is cleaner and more scalable.

#### Option 3: If you're okay with loose typing for now

const portfolioItems = ref<any[]>([])

> Not recommended long-term, but useful during debugging or prototyping.

Once you do that, your `loadItems()` function will work perfectly:

const loadItems = async () => {
  portfolioItems.value = await fetchPortfolioItems();
  console.log(portfolioItems.value);
}

Let me know if you want to make `createdAt` a `Date` or a Firebase `Timestamp` – I can help format it too.

Leave a Comment

Your email address will not be published. Required fields are marked *