일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 코테
- 동적계획법
- 백준
- 파이썬
- C++
- 안드로이드
- cos pro 1급
- android
- 안드로이드스튜디오
- 개발
- 알고리즘
- Flutter
- codingtest
- Algorithm
- cos
- 동적계획법과최단거리역추적
- DFS
- django
- vuejs
- cos pro
- Vue
- DFS와BFS
- 분할정복
- issue
- 코딩테스트
- BAEKJOON
- Python
- DART
- AndroidStudio
- 코드품앗이
- Today
- Total
Development Artist
[Flutter, Firebase, Issue] The argument type 'Object? Function()' can't be assigned to the parameter type 'Map<String, dynamic>'. 또는 The argument type 'DocumentReference<Object?>' can't be assigned to the parameter type 'DocumentSnapshot<Object?>'. 본문
[Flutter, Firebase, Issue] The argument type 'Object? Function()' can't be assigned to the parameter type 'Map<String, dynamic>'. 또는 The argument type 'DocumentReference<Object?>' can't be assigned to the parameter type 'DocumentSnapshot<Object?>'.
JMcunst 2022. 1. 12. 20:30이슈
1. 플러터 인프런 강의 중, 넷플릭스 UI 만들기가 있는데, 9강에서 Movie 모델의 fromSnapshot함수를 만드는 과정이었다.
2. 다음과 같이 snapshot.data와 snapshot.reference에서 이슈가 발생.
해결
1. pubspec.yaml에서 cloud_firebase 버전을 낮게 설정한다. 다운그레이드... cloud_firestore: ^0.12.9+5. 또한, cloud_firestore는 firebase_core에 의존성이 있어서, firebase_core: ^0.4.0+9. 로 맞춰 준다.
2. 하지만, 다운그레이드가 왠 말인가...! flutter에서 해결을 해보도록 하자.
3.0. fromSnapshot 함수의 인자로 <Map<String, dynamic>> 타입으로 지정을 해준다. 그리고 fromMap에서는 <Map<String, dynamic>>? 로 인자를 수정해준다. 그리고 그 아래 title, keyword, poster, like의 map 뒤에 ?를 붙여준다.
3.1. 해당 인자들이 무조건 온다면, null check로 title을 넣는 부분에만 map!['title']로 써도 가능하다.
원인
1. pubspec.lock에 cloud_firebase를 찾아보면 현재 프로젝트에 설치된 cloud_firebase 패키지의 버전을 알 수 있다. 혹자의 경우, 3.1.6이였는데, 해당 버전에서는 DocumentSnapshot 클래스가 제너릭을 따르게 되면서, 타입 T의 추상 메서드를 포함하고 있다.
abstract class DocumentSnapshot<T extends Object?>
2. 특히 위 코드에서 Object 뒤의 ? 이것이 원인인데, Type T가 Object? 를 상속하면서 DocumentSnapshot 클래스의 메소드인 data() 함수도 마찬가지로 T?를 return 하고, flutter에서는 T?에 대한 처리가 필요하다.
T? data();
3. 요약하자면, 기존에 DocumentSnapshot의 data로 <Map<String, dynamic>>을 채용하다가 T extends Object? 로 바꾸게 된 것이다. 쉽게 말하자면, 요런모양만 받을게~하다가 아무거나 가능해~로 바꿔서 너가 뭘로 올지 모르니 그것에 대한 처리가 필요해~라는 것이였다. (너무 비약하는 것 같긴한데...암튼 그렇다!)
참고
DocumentSnapshot : cloud_firebase version 0.13.7 / firebase_core version 0.4.0
class DocumentSnapshot {
platform.DocumentSnapshotPlatform _delegate;
final Firestore _firestore;
DocumentSnapshot._(this._delegate, this._firestore);
/// The reference that produced this snapshot
DocumentReference get reference =>
_firestore.document(_delegate.reference.path);
/// Contains all the data of this snapshot
Map<String, dynamic> get data =>
_CodecUtility.replaceDelegatesWithValueInMap(_delegate.data, _firestore);
/// Metadata about this snapshot concerning its source and if it has local
/// modifications.
SnapshotMetadata get metadata => SnapshotMetadata._(_delegate.metadata);
/// Reads individual values from the snapshot
dynamic operator [](String key) => data[key];
/// Returns the ID of the snapshot's document
String get documentID => _delegate.documentID;
/// Returns `true` if the document exists.
bool get exists => data != null;
}
DocumentSnapshot : cloud_firebase version 1.0.5 / firebase_core version 1.0.3
class DocumentSnapshot {
final FirebaseFirestore _firestore;
final DocumentSnapshotPlatform _delegate;
DocumentSnapshot._(this._firestore, this._delegate) {
DocumentSnapshotPlatform.verifyExtends(_delegate);
}
/// This document's given ID for this snapshot.
String get id => _delegate.id;
/// Returns the [DocumentReference] of this snapshot.
DocumentReference get reference => _firestore.doc(_delegate.reference.path);
/// Metadata about this [DocumentSnapshot] concerning its source and if it has local
/// modifications.
SnapshotMetadata get metadata => SnapshotMetadata._(_delegate.metadata);
/// Returns `true` if the [DocumentSnapshot] exists.
bool get exists => _delegate.exists;
/// Contains all the data of this [DocumentSnapshot].
Map<String, dynamic>? data() {
return _CodecUtility.replaceDelegatesWithValueInMap(
_delegate.data(), _firestore);
}
/// Gets a nested field by [String] or [FieldPath] from this [DocumentSnapshot].
///
/// Data can be accessed by providing a dot-notated path or [FieldPath]
/// which recursively finds the specified data. If no data could be found
/// at the specified path, a [StateError] will be thrown.
dynamic get(dynamic field) =>
_CodecUtility.valueDecode(_delegate.get(field), _firestore);
/// Gets a nested field by [String] or [FieldPath] from this [DocumentSnapshot].
///
/// Data can be accessed by providing a dot-notated path or [FieldPath]
/// which recursively finds the specified data. If no data could be found
/// at the specified path, a [StateError] will be thrown.
dynamic operator [](dynamic field) => get(field);
}
DocumentSnapshot : cloud_firebase version 3.1.6 / firebase_core version 1.11.0
@sealed
abstract class DocumentSnapshot<T extends Object?> {
/// This document's given ID for this snapshot.
String get id;
/// Returns the reference of this snapshot.
DocumentReference<T> get reference;
/// Metadata about this document concerning its source and if it has local
/// modifications.
SnapshotMetadata get metadata;
/// Returns `true` if the document exists.
bool get exists;
/// Contains all the data of this document snapshot.
T? data();
/// {@template firestore.documentsnapshot.get}
/// Gets a nested field by [String] or [FieldPath] from this [DocumentSnapshot].
///
/// Data can be accessed by providing a dot-notated path or [FieldPath]
/// which recursively finds the specified data. If no data could be found
/// at the specified path, a [StateError] will be thrown.
/// {@endtemplate}
dynamic get(Object field);
/// {@macro firestore.documentsnapshot.get}
dynamic operator [](Object field);
}