Home > Net >  Firebase Flutter Riverpod: How do I get the documentID from Firebase when using Riverpod to map valu
Firebase Flutter Riverpod: How do I get the documentID from Firebase when using Riverpod to map valu

Time:10-28

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,
    );
  }
}

  • Related