Ionic & AngularFireDatabase列表结果报错:Property 'map' does not exist on type '{}'
Hey there, let's work through this issue you're facing with Firebase data, TypeScript types, and Google Maps markers! That Property 'map' does not exist on type '{}' error usually boils down to TypeScript not knowing the actual shape of your data, or a mix-up in how you're accessing the Firebase snapshot data. Let's break down the fixes step by step:
1. First, Fix the TypeScript Type Issue
The root cause here is likely that TypeScript is inferring your Firebase snapshot data as an empty object ({}) instead of an array or structured data. To fix this:
- Define a clear interface for your map markers so TypeScript knows what shape to expect:
interface MapMarker { lat: number; lng: number; title?: string; description?: string; // Add any other fields you store in Firebase } - Explicitly type your Firebase collection query (if you're using AngularFire, which it sounds like you are):
When fetching data, add the generic type to your collection call to tell TypeScript what kind of data lives there:this.firestore.collection<MapMarker>('your-markers-collection')
2. Correctly Access the Snapshot Data
Chances are you're trying to call map directly on the Firebase snapshot object, but the snapshot itself doesn't have a map method. You need to access the docs property (an array of document snapshots) first:
- If using AngularFire's
snapshotChanges()(which gives you metadata like document IDs):import { map } from 'rxjs/operators'; // Inside your component/service this.markers$ = this.firestore.collection<MapMarker>('markers') .snapshotChanges() .pipe( map(actions => { // Map over the document actions array, not the snapshot itself return actions.map(action => { const markerData = action.payload.doc.data() as MapMarker; const id = action.payload.doc.id; return { id, ...markerData }; // Combine ID with marker data }); }) ); - If using raw Firebase JS SDK (async/await style):
const markerSnapshot = await getDocs(collection(db, 'markers')); const markers = markerSnapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })) as MapMarker[];
3. Fix RxJS Operator Import (If You're Using Observables)
You mentioned trying to fix RxJS imports but it didn't work—make sure you're using the pipeable operators (standard for RxJS 6+):
- Import
mapfromrxjs/operators, notrxjs:import { map } from 'rxjs/operators'; - Use the
pipe()method on your Observable to chain operators, instead of calling.map()directly on the Observable:// ❌ Old (deprecated) way // this.markers$.map(...) // ✅ Correct way this.markers$.pipe(map(...))
4. Test the Subscription
Once you've fixed the above, your subscription should start logging data correctly:
this.markers$.subscribe(markers => { console.log('Loaded markers:', markers); // Now pass this markers array to Google Maps to render markers });
Quick Check for Common Mistakes
- Did you accidentally call
mapon the snapshot object instead ofsnapshot.docs? That's the most common cause of themap doesn't exist on {}error. - Are you missing the generic type on your Firebase collection query? Without it, TypeScript can't infer the data shape.
- Is your RxJS import path correct? Double-check it's
rxjs/operators, not the oldrxjs/add/operator/mapsyntax.
内容的提问来源于stack exchange,提问作者Atoyansk

