I need to get the documentID of my documents in a firebase collection. The documentID is NOT stored as a field within the document. The ID was chosen by Firebase on import.
The other fields like name, phone, fullAddress, all display perfectly. How do I tap into the auto-generated docID using my Map/Model?
Any guidance is greatly appreciated.
Services:
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'restaurant_model.dart';
final restaurantProvider = StreamProvider.autoDispose((ref) {
final service = ref.watch(restaurantServiceProvider);
return service.restaurantModel();
});
final restaurantServiceProvider = Provider<RestaurantService>((ref) {
final firebase = FirebaseFirestore.instance;
return RestaurantService(firebase);
});
class RestaurantService {
final FirebaseFirestore _firebase;
RestaurantService(this._firebase);
Stream<List<RestaurantModel>> restaurantModel() {
return _firebase.collection('restaurantsPensacola').snapshots().map((event) => event.docs.map((e) => RestaurantModel.fromFirebase(e.data())).toList());
}
}
Model
import 'package:cloud_firestore/cloud_firestore.dart';
class RestaurantModel {
final String? name;
final String? phone;
final String? fullAddress;
final String? yearsInBusiness;
final String? priceRange;
final String? websiteLink;
final String? documentID;
RestaurantModel({
required this.name,
required this.phone,
required this.fullAddress,
required this.yearsInBusiness,
required this.priceRange,
required this.websiteLink,
required this.documentID,
});
factory RestaurantModel.fromFirebase(Map<String, dynamic> restaurantModel) {
return RestaurantModel(
name: restaurantModel['name'],
phone: restaurantModel['phone'],
fullAddress: restaurantModel['fullAddress'],
yearsInBusiness: restaurantModel['yearsInBusiness'],
priceRange: restaurantModel['priceRange'],
websiteLink: restaurantModel['websiteLink'],
//THIS IS WHERE I AM LOST AS THIS GENERATES ERROR
//Instance members can't be accessed from a factory constructor.
documentID: restaurantModel[documentID],
);
}
}
CodePudding user response:
The document ID can be accessed via e.id
. For your RestaurantModel, you would probably want to rename it to restaurantId
to be more accurate as to what it is describing, and just save the auto-generated document ID as the restaurantId at creation. You could also generate your own unique ID (with uuid package or something similar) and create a new document with that ID.
Example:
Future<dynamic> createRestaurantRecord(
String id, Map<String, dynamic> data) async {
return await _firestore.doc('restaurants/$id').set(data);
}
Your factory will not work as the documentID is not automatically stored with the rest of the doc's data.
CodePudding user response:
I was able to meet with my mentor and was shown I can get the ID from Firebase by adding e.id after e.data.
Stream<List<RestaurantModel>> restaurantModel() {
return _firebase.collection('restaurantsPensacola').snapshots().map(
(event) => event.docs.map((e) => RestaurantModel.fromFirebase(e.data(), e.id)).toList());
}
Then, it was recommended that I change the names slightly to make it easier to differentiate values. You'll see how I incorporated the documentID from Firebase.
import 'package:cloud_firestore/cloud_firestore.dart';
class RestaurantModel {
final String? name;
final String? phone;
final String? fullAddress;
final String? yearsInBusiness;
final String? priceRange;
final String? websiteLink;
final String? id;
RestaurantModel({
required this.name,
required this.phone,
required this.fullAddress,
required this.yearsInBusiness,
required this.priceRange,
required this.websiteLink,
required this.id,
});
factory RestaurantModel.fromFirebase(
Map<String, dynamic> restaurantModel, String documentIDFromFirebase) {
return RestaurantModel(
name: restaurantModel['name'],
phone: restaurantModel['phone'],
fullAddress: restaurantModel['fullAddress'],
yearsInBusiness: restaurantModel['yearsInBusiness'],
priceRange: restaurantModel['priceRange'],
websiteLink: restaurantModel['websiteLink'],
id: documentIDFromFirebase,
);
}
}