简体   繁体   中英

Firebase Flutter Riverpod: How do I get the documentID from Firebase when using Riverpod to map values across a model? Code Included

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

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM