/C:/Users/user/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/firebase_auth-3.8.0/lib/src/firebase_auth.dart:623:25: Error: The method 'signInWithAuthProvider' isn't defined for the class 'FirebaseAuthPlatform'.
 - 'FirebaseAuthPlatform' is from 'package:firebase_auth_platform_interface/src/platform_interface/platform_interface_firebase_auth.dart' ('/C:/Users/user/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/firebase_auth_platform_interface-6.8.0/lib/src/platform_interface/platform_interface_firebase_auth.dart').
Try correcting the name to the name of an existing method, or defining a method named 'signInWithAuthProvider'.
        await _delegate.signInWithAuthProvider(provider),

위와 같은 에러가 떴다........

 

내가 사용하고 있는 firebase_auth_platform_interface 버전이 이상한거 같아서(오류에는 6.8.0)으로 표시 pubspec.lock파일에 있는 버전을 6.7.0으로 낮췄더니 해결되었다.

플러터에서는 한 위젯의 여러 인스턴스를 만든다. 변경할 수 없는 위젯 인스턴스는 성능이 좋으므로 가능하면 const를 사용하는 것이 좋다. new, const 키워드를 사용하지 않으면 프레임워크가 가능한 const로 위젯을 추론하므로 크게 신경 쓰지 않아도 된다.

Widget build(BuildContext context){
	return Button(
    	child: Text("hello"),
        );
}

// 다음과 비교
Widget build(BuildContext context){
	return new Button(
    	child: Text("hello"),
        );
}

위의 Button 위젯은 new 키워드가 없고 아래의 Button은 new 키워드가 있다. 하지만 플러터가 알아서 처리하기 때문에 어떤 위젯이 상수(const)이고 아닌지 지정할 필요가 없다. 또한 클래스 인스턴스를 만들 때 new 를 사용할 필요가 없다. 이는 위젯뿐 아니라 객체에도 적용된다.

StatelessWidget을 서브클래싱 하는 대신 함수로 만들어서 위젯을 만들수도 있다.

Widget function({ String title, VoidCallback callback }) {
  return GestureDetector(
    onTap: callback,
    child: // some widget
  );
}
class SomeWidget extends StatelessWidget {
  final VoidCallback callback;
  final String title;

  const SomeWidget({Key key, this.callback, this.title}) : super(key: key);

  @override
  Widget build(BuildContext context) {
      return GestureDetector(
        onTap: callback,
        child: // some widget
      );
  }
}

첫 번째는 함수, 두번째는 클래스이다. 함수로 만드는게 훨 짧고 편해보이는데 두 방법의 차이는 무엇일까?

 

둘의 차이점은 크게 없어 보인다. 하지만 작으면서도 큰 차이점이 존재한다. 바로 위젯트리를 그릴경우이다.

 

함수의 경우에는

Container
  Container

위와 같이 그리지만 클래스의 경우에는

ClassWidget
  Container
    ClassWidget
      Container

위와 같이 그려 프레임워크가 업데이트 할때 작동하는 방식에 차이가 생긴다.

중요한 이유

기능을 사용하여 위젯 트리를 여러 위젯으로 분할하면 버그에 노출되고 일부 성능 최적화를 놓치게 됩니다.

함수를 사용하여 버그가 발생한다는 보장은 없지만 클래스를 사용하면 이러한 문제에 직면하지 않을 수 있습니다.

다음은 문제를 더 잘 이해하기 위해 직접 실행할 수 있는 Dartpad의 몇 가지 예제입니다.

결론

다음은 함수와 클래스 사용의 차이점을 보여줍니다.

  1. 클래스:
  • 성능 최적화 허용(const 생성자, 보다 세분화된 재구축)
  • 두 개의 다른 레이아웃 간 전환이 리소스를 올바르게 처리하는지 확인가능(함수는 이전 상태를 재사용할 수 있음).
  • 핫 리로드가 제대로 작동하는지 확인합니다(함수를 사용하면 핫 리로드가 중단될 수 showDialogs있음)
  • 위젯 인스펙터에 통합되어 있습니다.
    • ClassWidget화면에 무엇이 있는지 이해하는 데 도움이 되는 devtool이 표시하는 위젯 트리에서 볼 수 있습니다.
    • debugFillProperties 를 재정 의하여 위젯에 전달된 매개변수가 무엇인지 인쇄 할 수 있습니다.
  • 더 나은 오류 메시지
    예외가 발생하면(예: ProviderNotFound) 프레임워크는 현재 빌드 중인 위젯의 이름을 제공합니다. 기능 +에서만 위젯 트리를 분할한 경우 Builder오류에 유용한 이름이 없습니다.
  • 키를 정의할 수 있습니다
  • 컨텍스트 API를 사용할 수 있습니다
  1. 기능:
  • 코드가 적습니다(코드 생성 기능적 위젯을 사용하여 해결할 수 있음 ).

 

앱의 맨 윗부분에 main 함수가 있다.

void main() => runApp(MyApp));

다트 프로그램 처럼 앱도 main 함수가 진입점이다. 플러터에서는 runApp이라는 메서드로 최상위 위젯을 감싼다. 극단적으로 이 한 행의 코드만으로도 앱을 만들 수 있다. 기능이 다양한 앱은 main 함수에서 더 많은 작업을 수행한다. 하지만 이런 앱도 반드시 최상위 위젯을 runApp의 인수로 전달해 호출해야 한다.

[ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: Connection closed while receiving data
E/flutter (19034): #0      IOClient.send.<anonymous closure> (package:http/src/io_client.dart:50:13)
E/flutter (19034): #1      _invokeErrorHandler (dart:async/async_error.dart:16:24)
E/flutter (19034): #2      _HandleErrorStream._handleError (dart:async/stream_pipe.dart:282:9)
E/flutter (19034): #3      _ForwardingStreamSubscription._handleError (dart:async/stream_pipe.dart:161:13)
E/flutter (19034): #4      _HttpClientResponse.listen.<anonymous closure> (dart:_http/http_impl.dart:438:16)
E/flutter (19034): #5      _rootRunBinary (dart:async/zone.dart:1214:47)
E/flutter (19034): #6      _CustomZone.runBinary (dart:async/zone.dart:1107:19)
E/flutter (19034): #7      _CustomZone.runBinaryGuarded (dart:async/zone.dart:1013:7)
E/flutter (19034): #8      _BufferingStreamSubscription._sendError.sendError (dart:async/stream_impl.dart:376:15)
E/flutter (19034): #9      _BufferingStreamSubscription._sendError (dart:async/stream_impl.dart:394:16)
E/flutter (19034): #10     _BufferingStreamSubscription._addError (dart:async/stream_impl.dart:294:7)
E/flutter (19034): #11     _ForwardingStreamSubscription._addError (dart:async/stream_pipe.dart:132:11)
E/flutter (19034): #12     _addErrorWithReplacement (dart:async/stream_pipe.dart:180:8)
E/flutter (19034): #13     _HandleErrorStream._handleError (dart:async/stream_pipe.dart:287:11)
E/flutter (19034): #14     _ForwardingStreamSubscription._handleError (dart:async/stream_pipe.dart:161:13)
E/flutter (19034): #15     _rootRunBinary (dart:async/zone.dart:1214:47)
E/flutter (19034): #16     _CustomZone.runBinary (dart:async/zone.dart:1107:19)
E/flutter (19034): #17     _CustomZone.runBinaryGuarded (dart:async/zone.dart:1013:7)
E/flutter (19034): #18     _BufferingStreamSubscription._sendError.sendError (dart:async/stream_impl.dart:376:15)
E/flutter (19034): #19     _BufferingStreamSubscription._sendError (dart:async/stream_impl.dart:394:16)
E/flutter (19034): #20     _BufferingStreamSubscription._addError (dart:async/stream_impl.dart:294:7)
E/flutter (19034): #21     _SyncStreamControllerDispatch._sendError (dart:async/stream_controller.dart:812:19)
E/flutter (19034): #22     _StreamController._addError (dart:async/stream_controller.dart:690:7)
E/flutter (19034): #23     _StreamController.addError (dart:async/stream_controller.dart:642:5)
E/flutter (19034): #24     _HttpParser._reportBodyError (dart:_http/http_parser.dart:1158:22)
E/flutter (19034): #25     _HttpParser._onDone (dart:_http/http_parser.dart:865:9)
E/flutter (19034): #26     _rootRun (dart:async/zone.dart:1182:47)
E/flutter (19034): #27     _CustomZone.run (dart:async/zone.dart:1093:19)
E/flutter (19034): #28     _CustomZone.runGuarded (dart:async/zone.dart:997:7)
E/flutter (19034): #29     _BufferingStreamSubscription._sendDone.sendDone (dart:async/stream_impl.dart:410:13)
E/flutter (19034): #30     _BufferingStreamSubscription._sendDone (dart:async/stream_impl.dart:420:15)
E/flutter (19034): #31     _BufferingStreamSubscription._close (dart:async/stream_impl.dart:305:7)
E/flutter (19034): #32     _SyncStreamControllerDispatch._sendDone (dart:async/stream_controller.dart:816:19)
E/flutter (19034): #33     _StreamController._closeUnchecked (dart:async/stream_controller.dart:671:7)
E/flutter (19034): #34     _StreamController.close (dart:async/stream_controller.dart:664:5)
E/flutter (19034): #35     _Socket._onData (dart:io-patch/socket_patch.dart:2051:21)
E/flutter (19034): #36     _rootRunUnary (dart:async/zone.dart:1198:47)
E/flutter (19034): #37     _CustomZone.runUnary (dart:async/zone.dart:1100:19)
E/flutter (19034): #38     _CustomZone.runUnaryGuarded (dart:async/zone.dart:1005:7)
E/flutter (19034): #39     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:357:11)
E/flutter (19034): #40     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:285:7)
E/flutter (19034): #41     _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:808:19)
E/flutter (19034): #42     _StreamController._add (dart:async/stream_controller.dart:682:7)
E/flutter (19034): #43     _StreamController.add (dart:async/stream_controller.dart:624:5)
E/flutter (19034): #44     _RawSecureSocket._closeHandler (dart:io/secure_socket.dart:794:21)
E/flutter (19034): #45     _RawSecureSocket._tryFilter.<anonymous closure> (dart:io/secure_socket.dart:916:11)
E/flutter (19034): #46     _rootRunUnary (dart:async/zone.dart:1198:47)
E/flutter (19034): #47     _CustomZone.runUnary (dart:async/zone.dart:1100:19)
E/flutter (19034): #48     _FutureListener.handleValue (dart:async/future_impl.dart:143:18)
E/flutter (19034): #49     Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:696:45)
E/flutter (19034): #50     Future._propagateToListeners (dart:async/future_impl.dart:725:32)
E/flutter (19034): #51     Future._completeWithValue (dart:async/future_impl.dart:529:5)
E/flutter (19034): #52     Future._asyncCompleteWithValue.<anonymous closu
D/EGL_emulation(19034): eglMakeCurrent: 0xe7945000: ver 2 0 (tinfo 0xf2cc0be0)
D/EGL_emulation(19034): eglMakeCurrent: 0xe7945000: ver 2 0 (tinfo 0xf2cc0be0)

 

위와 같은 에러가 떴다 .....

왜일까 ....

 

찾아 보니 api랑 데이터를 주고 받는데 문제라고 한다.

 

try {
  final result =
      await http.post(url, body: encodedBody, headers: apiHeader);
  Map<String, dynamic> response = json.decode(result.body);

  print("Response: $response");

  return response;
} catch (error) {
  Map<String, dynamic> response = Map<String, dynamic>();
  response['success'] = false;
  response['message'] = error;
  return response;
}

 코드는 위와 같았는데 ㅋㅋㅋ

 

한참을 찾아도 api문제는 아니고 잘 오는데 가끔 위와 같은 connection error가 떠서

 

stackoverflow의 도움을 받으려 했지만 실패ㅋㅋㅋㅋ

 

알고 보니 .... android emulator문제.. 이놈의 에뮬...문제가 많다 ..

E/flutter (29506): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: Bad state: No element
E/flutter (29506): #0      List.first (dart:core-patch/growable_array.dart:250:5)
E/flutter (29506): #1      _MainScreenFullState._onLoad (package:follower/main/main_screen_full.dart:40:46)
E/flutter (29506): <asynchronous suspension>
E/flutter (29506): #2      _MainScreenFullState.initState.<anonymous closure> (package:follower/main/main_screen_full.dart:29:13)
E/flutter (29506): #3      new Future.delayed.<anonymous closure> (dart:async/future.dart:326:39)
E/flutter (29506): #4      _rootRun (dart:async/zone.dart:1182:47)
E/flutter (29506): #5      _CustomZone.run (dart:async/zone.dart:1093:19)
E/flutter (29506): #6      _CustomZone.runGuarded (dart:async/zone.dart:997:7)
E/flutter (29506): #7      _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1037:23)
E/flutter (29506): #8      _rootRun (dart:async/zone.dart:1190:13)
E/flutter (29506): #9      _CustomZone.run (dart:async/zone.dart:1093:19)
E/flutter (29506): #10     _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:1021:23)
E/flutter (29506): #11     Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:18:15)
E/flutter (29506): #12     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:397:19)
E/flutter (29506): #13     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:428:5)
E/flutter (29506): #14     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)
E/flutter (29506):

아주 간단하지만 어이 없는 오류다..

 

위와 같은 오류가 떴는데 이유는

 

print('List=' + '${List.first['name']}');
print('List=' + '${List.first['color']}');

 

위의 프린트 문이 문제 였는데 프린트 문 안의  List.first['name'] 이 null 이 었기 때문.. 즉 널 처리를 해주면 된다.

 

print('List=' + '${List.first['name'] ?? null}');
print('List=' + '${List.first['color'] ?? null}');​

 

혹은 인터넷을 뒤져 보니 아래와 같은 코드중에서 오류가 났다는 경우도 있었다.

 

@override
  void initState() {
    super.initState();
    GetIt.I.get<SettingsLogic>().applyThemeFromPrefs();
  }

// file: settings_logic.dart

void applyThemeFromPrefs() {
    SharedPreferences.getInstance().then((prefs) {
      var themeName = prefs.getString("theme");
      _applyTheme(themeName);
    });
  }

  void _applyTheme(String themeName) {
    AppTheme appTheme = AppTheme.values.singleWhere((v) => describeEnum(v) == themeName);
    _currentTheme = appTheme;
    _streamController.sink.add(AppThemeChangedEvent(appTheme));
  }

...
// listener to theme changing

class FxoApp extends StatelessWidget {
  final SettingsLogic settings = GetIt.I.get<SettingsLogic>();

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<AppThemeChangedEvent>(
      stream: settings.themeStream,
      initialData: AppThemeChangedEvent(AppTheme.Light),
      builder: (context, snapshot) {
        return MaterialApp(
          title: AppName,
          theme: appThemeData[snapshot.data.appTheme],
...

위의 문제에서는 

 

.firstWhere((a) => a == b, orElse:() => null) 로 똑같은 null 처리를 해주면 된다.

 

구글과 Flutter!!!!!후후후

 


Flutter?

플러터(Flutter)는 구글이 개발한 오픈 소스 모바일 애플리케이션 개발 프레임워크이다. 안드로이드, iOS용 애플리케이션 개발을 위해, 또 구글 푸크시아용 애플리케이션 개발의 주된 방식으로 사용된다.

 

잠깐 역사를 알고 가자면 "플러터의 최초 버전의 코드명은 "Sky"(스카이)이며안드로이드운영 체제에서 실행되었다. 2015년다트개발자 서밋에서 공개되었으며 120프레임/초로 꾸준히렌더링이 가능하도록 의도되었다고 언급되었다.상하이의 구글 개발자의 날 키노트 중에 구글은 플러터 1.0 전의 마지막 대형 릴리스인 플러터 릴리스 프리뷰 2를 발표하였다. 2018년 12월 4일, 플러터 1.0이 플러터 라이브 이벤트에서 공개되었으며 프레임워크의 최초의 안정판으로 언급되었다." 라고 합니다.

+ Recent posts