Home > OS >  Flutter firebase fromMap
Flutter firebase fromMap

Time:12-29

I'm having a problem converting an array property in a firebase database.

Ive got a database in firebase with a collection of "faqs". A couple of propertie of an faq is an array of strings

firebase model

I attempt to convert the firebase from a map to an object like so:

enter image description here

I get an error of:

enter image description here

The issue relates to the "tags" and "images" property of the model.

Could someone please explain why it fails and how i correct the problem please.

full model class below:

import 'dart:convert';

import 'package:collection/collection.dart';

class Faq {
  String faqId;
  String? question;
  String? answer;
  List<String>? tags;
  List<String>? images;

  Faq(
      {required this.faqId,
      this.question,
      this.answer,
      this.tags,
      this.images});

  @override
  String toString() {
    return 'Faq(faqId: $faqId, question: $question, answer: $answer, tags: $tags, images: $images)';
  }

  factory Faq.fromMap(Map<String, dynamic> data) => Faq(
        faqId: data['faqId'] as String,
        question: data['question'] as String?,
        answer: data['answer'] as String?,
        tags: data['tags'] as List<String>?,
        images: data['images'] as List<String>?,
      );

  Map<String, dynamic> toMap() => {
        'faqId': faqId,
        'question': question,
        'answer': answer,
        'tags': tags,
        'images': images,
      };

  /// `dart:convert`
  ///
  /// Parses the string and returns the resulting Json object as [Faq].
  factory Faq.fromJson(String data) {
    return Faq.fromMap(json.decode(data) as Map<String, dynamic>);
  }

  /// `dart:convert`
  ///
  /// Converts [Faq] to a JSON string.
  String toJson() => json.encode(toMap());

  Faq copyWith({
    required String faqId,
    String? question,
    String? answer,
    List<String>? tags,
    List<String>? images,
  }) {
    return Faq(
      faqId: faqId,
      question: question ?? this.question,
      answer: answer ?? this.answer,
      tags: tags ?? this.tags,
      images: images ?? this.images,
    );
  }

  @override
  bool operator ==(Object other) {
    if (identical(other, this)) return true;
    if (other is! Faq) return false;
    final mapEquals = const DeepCollectionEquality().equals;
    return mapEquals(other.toMap(), toMap());
  }

  @override
  int get hashCode =>
      faqId.hashCode ^
      question.hashCode ^
      answer.hashCode ^
      tags.hashCode ^
      images.hashCode;
}

CodePudding user response:

Try this when you are parsing your response:

factory Faq.fromMap(Map<String, dynamic> data) => Faq(
    faqId: data['faqId'] as String,
    question: data['question'] as String?,
    answer: data['answer'] as String?,
    tags: List<String>.from(data["tags"] ?? []); // <--- change this
    images: data['images'] as List<String>?,
);

CodePudding user response:

try this instead in the tags in your fromMap() :

// ...
tags: (data["tags"] as List).map((elem) => elem.toString()).toList(),

so the new method will be:.

factory Faq.fromMap(Map<String, dynamic> data) => Faq(
        faqId: data['faqId'] as String,
        question: data['question'] as String?,
        answer: data['answer'] as String?,
        tags: (data["tags"] as List).map((elem) => elem.toString()).toList(),            
        images: data['images'] as List<String>?,
      );
  • Related