简体   繁体   English

Firebase Flutter Riverpod:在使用 Riverpod 跨模型映射值时,如何从 Firebase 获取 documentID? 包含代码

[英]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.我需要在 firebase 集合中获取我的文档的 documentID。 The documentID is NOT stored as a field within the document. documentID 不存储为文档中的字段。 The ID was chosen by Firebase on import.该 ID 由 Firebase 在导入时选择。

The other fields like name, phone, fullAddress, all display perfectly.其他字段,如姓名、电话、完整地址,都完美显示。 How do I tap into the auto-generated docID using my Map/Model?如何使用我的地图/模型访问自动生成的 docID?

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 .可以通过e.id访问文档 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.对于您的 RestaurantModel,您可能希望将其重命名为restaurantId以使其描述的内容更加准确,并且只需在创建时将自动生成的文档 ID 保存为 restaurantId。 You could also generate your own unique ID (with uuid package or something similar) and create a new document with that ID.您还可以生成自己的唯一 ID(使用 uuid 包或类似的东西)并使用该 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.您的工厂将无法工作,因为文档 ID 不会自动与文档的其余数据一起存储。

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.我能够与我的导师会面,并被告知我可以通过在 e.data 之后添加 e.id 从 Firebase 获取 ID。

    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.您将看到我是如何从 Firebase 合并 documentID 的。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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