비쥬얼코드 visual code 유용한 확장프로그램
비쥬얼코드 
flutter extension 
- flutter Dart Code : 플러터 실행환경 
- Awesome Flutter Snippets : 빠른생산성 
- dart-import : 서드파트,디벨로퍼 패키지 구분, shift+ctrl+p 
- Pubspec Assist : vs내에서 extension을 바로 확인 : shift+ctrl+p -> pubspect 를 찾아서 모듈검색 
- Dart Data Class Generator : dart클래스를 쉽게 만든다(제작자 recardo emerson) 
- Error Lens 
- Image preview :  
- Bracket Pair Colorizer 2  
- Gruvbox Concoctis : theme 
- vscode-icons 
- Freezed 
- Flutter Riverpod Snippets 
- Remove Comments    코멘트를 지워준다 : shift+ctrl+p  -> "Remove all comments" 입력후 엔터  
- Peacock : 메뉴영역색깔 변경 
- indent-rainbow : 들여쓰기 영역 색깔 구분 지원 
- Flutter UI guides 
  Setting > search for 'preview flutter ui guides' > Dart > Preview Flutter UI Guides,Preview Flutter Ui guideds Custom Tracking 두개항목 체크 
  에서 체크 하고 재시작 
==================================== 
플러터 개발시 const 일일이 붙이기 싫을때 
세팅 
1. ctrl+shift+P  입력 또는 메뉴의 view - Command Pallet 선택 후 
   입력창에 Preferences: Open User Setting(json)을 입력하여해당 메뉴를 선택하면 json 파일이 열림 
setting.json 파일내 
"[dart]": { 
    "editor.codeActionsOnSave": { 
        "source.fixAll": true   // vscode 가 업데이트 되면서  "explicit" 값으로 바뀜 
    }, 
} 
--- 
vs 코드에서 프로젝트 생성 command 명령  
flutter create 프로젝트명 
--- 
vs 코드에서 에뮬레이터 실행환경 ( 안드로이드 스튜디오의 AVD MANAGER에서 Create Virtual Device 로 AVD를 설치해두어야함) 
VSCode command palette 실행 : ctrl+shift+p 에서 flutterse 입력하 AVD 선택하면됨 
==================================== 
vs 코드 라인정렬 
shift + alt + F 
vs 코드 위젯 Wrap 메뉴 나오기 
ctrl + . 
================================ 
pubspc.yaml 
flutter pub add 패키지명 
flutter pub get 
설정 
-개발시 귀찮은 lint룰 제거 
  analysis_options.yaml 파일의 include: package:flutter_lints/flutter.yaml 라인 주석처리함 
   
====================================== 
디버그 배너 제거 
 메인의 MaterialApp 속성에서 debugShowCheckedModeBanner: false, 
  
======================================= 
리스트뷰 ListView 
리스트뷰에서 컨텐츠가 Column 영역 의 중간으로 가려면 shrinkWrap: true로 주면 된다. 
ListView( 
            shrinkWrap: true, 
            children: [] 
) 
======================================= 
다트 getter 샘플 
  
  
enum AppState{ initial, loading, success, error,}  // 이넘 
class Appprovider with ChangeNotifier{ 
 AppState _state = AppState.initial; 
 AppState get state => _state;  // 게터 
 notifyListeners();  // 리스너들에게 변경이되었다고 알려줌 
} 
//리스너 사용법 예제 
context.read<클래스>().함수();  // changeNotifier를 믹스인한 클래스의 함수가 실행됨 
final appState = context.watch<Appprovider>().state; // state값이 변경될때마다 appstate에 저장 
============================================================== 
Riverpod 
패키지  
 - riverpod_lint : 개발자들의 실수를 줄여줌  
    -> development dependency에 추가, custom_lint 도 함께 설치되어야함 
    -> analysis_options.yaml 파일 내  
      analyzer: 
     plugins: 
   - custom_lint  항목 추가 
  
Riverpod 코드 제네레이션 사용하기 위한 dependencies 
  dependencies: 
    riverpod_annotation: ^2.2.1 
  dev_dependencies: 
    build_runner : ^2.4.6 
riverpod_generator: ^2.4.4 
============================================================== 
구글 폰트 
flutter pub add google_fonts 
============================================================= 
uuid 생성 (랜덤id) 
flutter pub add uuid 
import 'package:uuid/uuid.dart'; 
final uuid = Uuid();   
class Place { 
   Place({required this.title }) : id = uuid.v4();  //id 생성 
  final String id; 
  final String title;  
} 
============================================================= 
플러터 로컬 장치에 데이터를 저장할때 사용하는 패키지 
1. path_provider : 이미지를 저장해야할 경로에 쉽게 접근할수 있게해줌 
  -  flutter pub add path_provider 
2. path 1.8.3 : 파일 경로 작업 프로세스를 단순하게 해줌 ( 수동으로 잡는 경로를 이패키지는 단순히 경로를 쉽게 구성해 다양한 운영체제에서 작동하게 함) 
  - flutter pub add path 
- 장치에 DB를 저장하는 건 여러 방식이 있는데 둘중 하나 쓰면 됨 sqflite 또는 shared_preferences 
3. sqflite : sql 명령을 이용해 장치에 데이터를 저장함 
4. shared_preferences : 장치에 데이터를 저장할수있도록 도와줌, sqflite 보단 단순하며 key,value 로저장함 
======================================================= 
 플러터 포커스제거(키보드창 제거)  
FocusScope.of(context).unfocus();  //입력창에서 포커스를 제거 함으로써 키보드를 비활성화시키는 효과 
======================================================= 
 플러터 Form validation 
  
 final _form = GlobalKey<FormState>();  // form 영역변수 선언   
   
  void _submit() { //버튼에서 해당 함수 실행 
    final isValid = _form.currentState!.validate();  // 유효성 검사 
    if(isValid){ // 정상이라면 
      _form.currentState!.save(); //Form 영역의 onSaved 속성 실행 
    } 
  } 
   
  child: Form( 
  key: _form,  // Form form키 매핑 
  child: Column(...) 
  ) 
   
  TextFormField( 
decoration: const InputDecoration( 
  labelText: 'Password', 
), 
obscureText: true, 
validator: (value) { 
  if (value == null || value.trim().length < 6) { 
return 'Password must be at least 6 characters long.'; 
  } 
  return null; 
}, 
onSaved: (value) { 
  _enteredPassword = value!; 
}, 
  ), 
=======================================================    
파이어 베이스 설치 
1.SDK 설치 
 npm install -g firebase-tools 
 get-executionpolicy 
 set-ExecutionPolicy RemoteSigned 
 firebase 
 firebase login 
 firebase projects:list 
 dart pub global activate flutterfire_cli 
2.모듈설치  
 flutter pub add firebase_core   <= 파이어베이스 코어 
 flutter pub add firebase_auth   <= 파이어베이스 인증모듈 
 flutterfire configure 
 flutter pub add firebase_storage  <= 이미지저장용 스토리지 모듈 
 flutter pub add firebase_messaging  <= FCM 플러그인 설치 
  
  
=======================================================    
파이어 베이스 설치시 오류 
1. 터미널 PSSecurityException 에러 
    ->해당 에러는 powershell의 스크립트 실행 정책 오류 메시지로 powerShell의 Set-ExecutionPolicy 설정 변경이 필요  
Windows PowerShell 스크립트 실행 정책 옵션 설명 
Restricted    : PowerShell 대화형 모드에서만 실행할 수 있고, 다른 곳에서는 스크립트 실행 불가  
AllSigned     : 신뢰한 사용자가 서명한 스크립트만 실행할 수 있습니다. 
RemoteSigned  : 스크립트를 실행하기 전에는 신뢰할 수 있는 게시자가 먼저 서명을 해야합니다. 
Unrestricted  : 제한 없음 
해결방법 
1. Windows PowerShell 관리자 모드 실행 
2. get-executionpolicy 입력 (생략가능) = 현재 내 컴퓨터의 스크립트 실행 정책 확인 
3. Set-ExecutionPolicy RemoteSigned 입력 후 엔터 
4. Y 입력  
5. get-executionpolicy 입력 (변경 확인) 
6. webStorm의 현재 실행 중인 터미널 종료 후 새로운 터미널 실행 
2. Failed to list Firebase projects 오류 
    -> firebase login --reauth 를 통해 해결 
================================================================ 
플러터 이미지 선택 모듈 
flutter pub add image_picker   <== 이미지 선택 라이브러리 
================================================================ 
파이어베이스 스토리지 이미지 저장 : user_images라는 폴더를 만들고 아래 jpg파일을 생성 
 FirebaseStorage.instance.ref().child('user_images').child('${userCredentials.user!.uid}.jpg'); 
 생성한 파일명에 파일 저장 
 await storageRef.putFile(_selectedImage!); 
 저장된 파일 경로 가져오기 
 final imageUrl = await storageRef.getDownloadURL(); 
================================================================ 
파이어 베이스 접속한 ID 가져오기 
final user = FirebaseAuth.instance.currentUser!; 
================================================================ 
Firestore Database (파이어베이스 스토어드 데이터베이스) 
  1. 파이어베이스 설정 
!!! 데이터베이스 console에서 생성후 native 모드로 해서 파이어베이스 화면에서 규칙(rule 변경: 인증된사용자만) 
=> allow read, write: if request.auth != null; 
  2. 플러터 라이브러리 설치 
flutter pub add cloud_firestore 
  3. 데이터 저장 방법 
     FirebaseFirestore.instance 
            .collection('users') 
            .doc(userCredentials.user!.uid) 
            .set({ 
  'username': _enteredusername, 
  'email': _enteredEmail, 
  'image_url': imageUrl, 
}); 
4. 데이터 가져와 사용하기 
final user = FirebaseAuth.instance.currentUser!; 
final userData = await FirebaseFirestore.instance 
.collection('users') 
.doc(user.uid) 
.get(); 
print( userData.data()!['username'] ); 
5. 플러터에서 파이어베이서 문서 수신으로 UI 처리 ( StreamBuilder 위젯에서  FirebaseFirestore스냅샷하면 변경될때 문서수신받을수있음 ) 
 StreamBuilder(stream: FirebaseFirestore.instance.collection('chat').snapshots(), builder: builder) 
6. 빌드시 오류 해결방법 
  android\app\build.gradle 파일을 열어 아래 부분을 추가 한다. 
   defaultConfig { 
applicationId "com.example.chat_app" 
minSdkVersion 19   // minsdk버전 변경 
targetSdkVersion flutter.targetSdkVersion 
versionCode flutterVersionCode.toInteger() 
versionName flutterVersionName 
multiDexEnabled true   //해당 부분 추가!!!!!!!!!!!!! 
} 
7. 샘플 목록 뿌리기 
@override 
  Widget build(BuildContext context) { 
return StreamBuilder( 
  stream: FirebaseFirestore.instance 
  .collection('chat') 
  .orderBy('createdAt', descending: false) 
  .snapshots(),  //정렬해서 문서 수신 하기 
  builder: (ctx, chatSnapshots) { 
if (chatSnapshots.connectionState == ConnectionState.waiting) { 
  return const Center( 
child: CircularProgressIndicator(), 
  ); 
} 
if (!chatSnapshots.hasData || chatSnapshots.data!.docs.isEmpty) { 
  return const Center( 
child: Text('Nomessages found.'), 
  ); 
} 
if (chatSnapshots.hasError) { 
  return const Center( 
child: Text('Something went wrong...'), 
  ); 
} 
final loadedmessages = chatSnapshots.data!.docs; 
return ListView.builder( 
  itemCount: loadedmessages.length, 
  itemBuilder: (ctx, index) => 
  Text(loadedmessages[index].data()['text']),  // 데이터 출력 
); 
  }, 
); 
  } 
   
================================================================ 
Firestore FMC (파이어베이스 스토어드 데이터베이스) 
void setupPushNotification() async { 
    final fcm = FirebaseMessaging.instance; 
    await fcm.requestPermission();  // 권한확인 
    final token = await fcm.getToken(); // 토큰  
    print(token); 
  }