QuisApp / flutter_contacts

MIT License
83 stars 138 forks source link

fromJSON is not working with thumbnail #92

Open nagringapp opened 1 year ago

nagringapp commented 1 year ago

I did use the toJSon to save it in the database, however the toJSON does now work when the data contains thumbnail.

type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String'

nagringapp commented 1 year ago

If someone needs, I've created those methods that is working


  static String fromContact(Contact contact) {
    final id = contact.id;
    final displayName = contact.displayName;
    final name = jsonEncode(contact.name.toJson());
    final thumbnail = contact.thumbnail;
    final accounts = jsonEncode(contact.accounts.map((e) => e.toJson()).toList());
    final addresses = jsonEncode(contact.addresses.map((e) => e.toJson()).toList());
    final emails = jsonEncode(contact.emails.map((e) => e.toJson()).toList());
    final events = jsonEncode(contact.events.map((e) => e.toJson()).toList());
    final groups = jsonEncode(contact.groups.map((e) => e.toJson()).toList());
    final organizations = jsonEncode(contact.organizations.map((e) => e.toJson()).toList());
    final phones = jsonEncode(contact.phones.map((e) => e.toJson()).toList());
    final socialMedias = jsonEncode(contact.socialMedias.map((e) => e.toJson()).toList());
    final websites = jsonEncode(contact.websites.map((e) => e.toJson()).toList());

    Map<String, String?> data = {
      'id': id,
      'displayName': displayName,
      'name': name,
      // 'thumbnail': thumbnail,
      'accounts': accounts,
      'addresses': addresses,
      'emails': emails,
      'events': events,
      'groups': groups,
      'organizations': organizations,
      'phones': phones,
      'socialMedias': socialMedias,
      'websites': websites,
      'thumbnail': thumbnail == null ? null : base64Encode(thumbnail)
    };
    return jsonEncode(data);
  }

  static Contact fromJson(String data) {

    final json = Map<String, String?>.from(jsonDecode(data));
    try {
      final contact = Contact(
        id: json['id'] ?? '',
        displayName: json['displayName'] ?? '',
        name: json['name'] != null ? Name.fromJson(jsonDecode(json['name']!)) : null,
        accounts: json['accounts'] != null ? List.from(jsonDecode(json['accounts']!)).map((e) => Account.fromJson(e)).toList() : null,
        addresses: json['addresses'] != null ? List.from(jsonDecode(json['addresses']!)).map((e) => Address.fromJson(e)).toList() : null,
        emails: json['emails'] != null ? List.from(jsonDecode(json['emails']!)).map((e) => Email.fromJson(e)).toList() : null,
        groups: json['groups'] != null ? List.from(jsonDecode(json['groups']!)).map((e) => Group.fromJson(e)).toList() : null,
        events: json['events'] != null ? List.from(jsonDecode(json['events']!)).map((e) => Event.fromJson(e)).toList() : null,
        organizations: json['organizations'] != null ? List.from(jsonDecode(json['organizations']!)).map((e) => Organization.fromJson(e)).toList() : null,
        phones: json['phones'] != null ? List.from(jsonDecode(json['phones']!)).map((e) => Phone.fromJson(e)).toList() : null,
        websites: json['websites'] != null ? List.from(jsonDecode(json['websites']!)).map((e) => Website.fromJson(e)).toList() : null,
        socialMedias: json['socialMedias'] != null ? List.from(jsonDecode(json['socialMedias']!)).map((e) => SocialMedia.fromJson(e)).toList() : null,
        thumbnail: json['thumbnail'] != null ? base64Decode(json['thumbnail']!) : null
      );

      return contact;
    } catch (e) {
      return Contact();
    }

  }
joachim-quis commented 1 year ago

Thanks for reporting! Will look into it shortly.

yassinsameh commented 1 year ago

@joachim-quis I believe this occurs because the update method only tries to store the high-res photo and not the thumbnail. The line ~415 in the file SwiftFlutterContactsPlugin.swift:

 if let photo = args["photo"] as? FlutterStandardTypedData {
            contact.imageData = photo.data
        }

@nagringapp I would suggest using the thumbnail as the photo variable as a workaround or fetch the contact you are updating with the "withPhoto" variable being true.

fabianlj commented 1 year ago

This may help. This helped me understand my problem when reading contacts from Firestore. https://stackoverflow.com/questions/64055981/type-listdynamic-is-not-a-subtype-of-type-uint8list

Just copy this method and give it your List and it will cast & return Unit8List that can be used anywhere in Flutter such as image.memory() .

Uint8List _getImageBinary(List<dynamic> dynamicList) {
    List<int> intList = dynamicList.cast<int>().toList(); //This is the magical line.
    Uint8List data = Uint8List.fromList(intList);
    return data;
  }

so need to change these lines in fromJson . I just created my own method.

thumbnail: (json['thumbnail'] != null) ? _getImageBinary(json['thumbnail']) : json['thumbnail'] as Uint8List?,
photo: (json['photo'] != null) ? _getImageBinary(json['photo']) : json['photo'] as Uint8List?,