簡體   English   中英

如何在 firebase (Flutter/dart) 中添加具有 DocumentReference 類型的對象?

[英]How to add an Object with a DocumentReference type in firebase (Flutter/dart)?

我想在 firebase 的帖子文檔中引用一個類別文檔。 這是我的數據類,我也在使用凍結和 json_serializer:

part 'post_dto.freezed.dart';
    part 'post_dto.g.dart';
    part 'category_dto.freezed.dart';
    part 'category_dto.g.dart';
    
    @freezed
    abstract class PostDTO with _$PostDTO {
      const PostDTO._();
    
      const factory PostDTO({
        @JsonKey(ignore: true) String? id,
        required String title,
        required String description,
        @DocumentReferenceConveter() DocumentReference? categoryReference,
      }) = _PostDTO;
    
      factory PostDTO.fromJson(Map json) =>
          _$PostDTOFromJson(json);
    
      factory PostDTO.fromFireStore(DocumentSnapshot document) {
        Map data = document.data() as Map;
        return PostDTO.fromJson(data).copyWith(id: document.id);
      }
    }
    
    @freezed
    abstract class CategoryDTO with _$CategoryDTO {
      const CategoryDTO._();
    
      const factory CategoryDTO({
        required String icon,
        required String name,
      }) = _CategoryDTO;
    
     factory CategoryDTO.fromFireStore(DocumentSnapshot document) {
        Map data = document.data() as Map;
        return CategoryDTO.fromJson(data);
      }
    
      factory CategoryDTO.fromJson(Map json) =>
          _$CategoryDTOFromJson(json);
    }

當我運行 build_runner 時出現此錯誤:

[SEVERE] json_serializable:json_serializable on lib/infrastructure/post/post_dto.dart:
    
    Could not generate `fromJson` code for `categoryReference`.
    To support the type `DocumentReference` you can:
    * Use `JsonConverter`
      https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonConverter-class.html
    * Use `JsonKey` fields `fromJson` and `toJson`
      https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/fromJson.html
      https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/toJson.html
    package:UPLFY/infrastructure/post/post_dto.freezed.dart:373:41
        ╷
    373 │   final DocumentReference? categoryReference;
        │                                         ^^^^^^^^^^^^^^^^^
        ╵
    [INFO] Running build completed, took 2.5s
    
    [INFO] Caching finalized dependency graph...
    [INFO] Caching finalized dependency graph completed, took 44ms
    
    [SEVERE] Failed after 2.5s

所以嘗試使用 JsonConverter 但我不確定如何將 json 對象轉換為 DocumentReference ...

class DocumentReferenceConveter
        implements JsonConverter, Object> {
      const DocumentReferenceConveter();
    
      @override
      DocumentReference fromJson(Object json) {
        return //TODO: Convert json to DocumentReference
      }
    
      @override
      Object toJson(DocumentReference documentReference) =>
          documentReference;
    }

我一直在調查,我發現存在與某些版本的分析器包相關的問題 我把它留在這里,以防它對社區中的某個人有用(如果您使用“0.39.15”或“0.39.16”版本,這可能是原因)。 如果是這種情況,您現在可以在 pubspec.yaml 中設置覆蓋:

dependency_overrides:
  analyzer: '0.39.14'

此外,您應該在以下之后清除所有緩存:

flutter clean
flutter pub cache repair
flutter pub run build_runner clean

我能夠從我在網上找到的研究中整理出我的解決方案,到目前為止,我想出了這個。

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:json_annotation/json_annotation.dart';

class DocumentReferenceJsonConverter
    implements JsonConverter<DocumentReference?, Object?> {
  const DocumentReferenceJsonConverter();

  @override
  DocumentReference? fromJson(Object? json) {
    return tryCast<DocumentReference>(json);
  }

  @override
  Object? toJson(DocumentReference? documentReference) => documentReference;
}
T? tryCast<T>(value) {
  return value == null ? null : value as T;
}
...
import 'package:freezed_annotation/freezed_annotation.dart';

part 'user_profile.freezed.dart';
part 'user_profile.g.dart';

@freezed
class UserProfile with _$UserProfile {
  const UserProfile._();

  @TimestampConverter()
  @DocumentReferenceJsonConverter()
  @JsonSerializable(
    explicitToJson: true,
    fieldRename: FieldRename.snake,
    includeIfNull: false,
  )
  factory UserProfile({
    @JsonKey(ignore: true) DocumentReference? reference,
    String? avatarUrl,
    required String email,
    required String firstName,
    required String lastName,
    Gender? gender,
    DateTime? birthday,
    String? additionalInfo,
    Contact? contact,
    DocumentReference? familyReference,
    DateTime? createdAt,
  }) = _UserProfile;

  factory UserProfile.empty() => UserProfile(email: '', firstName: '', lastName: '');

  factory UserProfile.fromJson(Map<String, dynamic> json) => _$UserProfileFromJson(json);

  factory UserProfile.fromDocument(DocumentSnapshot documentSnapshot) {
    final data = documentSnapshot.data();
    return data != null
        ? UserProfile.fromJson(data as Map<String, dynamic>)
            .copyWith(reference: documentSnapshot.reference)
        : UserProfile.empty();
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM