kokogento
@kokogento (ここ げんと)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Flutter ユーザー情報取得時のエラー Unhandled Exception: type 'Timestamp' is not a subtype of type 'DateTime'

解決したいこと

FlutterでFirebase + Providerでユーザー情報を取得する際に、下記のようなエラーでクラッシュします。。。

[VERBOSE-2:ui_dart_state.cc(209)] Unhandled Exception: type 'Timestamp' is not a subtype of type 'DateTime'
#0      User.fromSnap
package:lovedan/models/user.dart:19
#1      AuthMethods.getUserDetails
package:lovedan/resources/auth_methods.dart:14
<asynchronous suspension>
#2      UserProvider.refreshUser
package:lovedan/providers/user_provider.dart:12
<asynchronous suspension>
#3      _ResponsiveLayoutState.addData
package:lovedan/responsive/responsive_layout.dart:29
<asynchronous suspension>
Restarted application in 654ms.
Reloaded 1 of 743 libraries in 141ms.

ユーザー情報にはcreatedAtでアカウント作成時の日時を持たせているのですが、それがうまく変換できていないようです。
この問題を解消するにはどのようなコードを書けば良いでしょうか?

以下のように.toDate()をどこかで使えば良いと言うのはわかりますが、、、どのように書けばいいかわからないです:sweat:

DateTime dateTime = documents[i].data["duedate"].toDate();

該当のコード

user.dart

lib/models/user.dart
import 'package:cloud_firestore/cloud_firestore.dart';

class User {
  final String uid;
  final DateTime createdAt;
  final List watchingList;

  const User({
    required this.uid,
    required this.createdAt,
    required this.watchingList,
  });

  static User fromSnap(DocumentSnapshot snap) {
    var snapshot = snap.data() as Map<String, dynamic>;

    return User(
      uid: snapshot["uid"],
      createdAt: snapshot["createdAt"],
      watchingList: snapshot["watchingList"],
    );
  }

  Map<String, dynamic> toJson() => {
        "uid": uid,
        "createdAt": createdAt,
        "watchingList": watchingList,
      };
}

user.provider

import 'package:flutter/widgets.dart';
import 'package:lovedan/models/user.dart';
import 'package:lovedan/resources/auth_methods.dart';

class UserProvider with ChangeNotifier {
  User? _user;
  final AuthMethods _authMethods = AuthMethods();

  User get getUser => _user!;

  Future<void> refreshUser() async {
    User user = await _authMethods.getUserDetails();
    notifyListeners();
  }
}

auth_methods.dart

import 'package:lovedan/models/user.dart' as model;
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';

class AuthMethods {
  final FirebaseFirestore _firestore = FirebaseFirestore.instance;
  final FirebaseAuth _auth = FirebaseAuth.instance;

  // get user detals
  Future<model.User> getUserDetails() async {
    User currentUser = _auth.currentUser!;
    DocumentSnapshot documentSnapshot =
        await _firestore.collection('users').doc(currentUser.uid).get();
      
    // ここのfromSnapが失敗する
    return model.User.fromSnap(documentSnapshot);
  }

試したこと

  Future<model.User> getUserDetails() async {
    User currentUser = _auth.currentUser!;
    DocumentSnapshot documentSnapshot =
        await _firestore.collection('users').doc(currentUser.uid).get();
    final date = documentSnapshot.get('createdAt').toDate();
    print(date);

    return model.User.fromSnap(documentSnapshot);
  }

これでdata2022-09-13 22:06:43.759のようにDateTimeに変換できることは確認できているのですが、documentSnapshotをどう変換すれば良いかがわからずです。。。

0

1Answer

#0      User.fromSnap
package:lovedan/models/user.dart:19

と出ているようにエラーは user.dart の19行目

    return User(
      uid: snapshot["uid"],
      createdAt: snapshot["createdAt"], // ここ
      watchingList: snapshot["watchingList"],
    );

で起きているのですから、 snapshot["createdAt"].toDate() とすればいいのでは?

1Like

Comments

  1. @kokogento

    Questioner

    user.dart:19を`snapshot["createdAt"].toDate()`にすると解消されました!!!
    エラーメッセージを見落として、深く考えすぎていたようです・・・・
    ありがとうございます!

Your answer might help someone💌