묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨[Bloc 응용] 실전 앱 만들기 (책 리뷰 앱) : SNS 로그인, Firebase 적용, Bloc 상태 관리, GoRouter
GoogleService-Info.plist > REVERSED_CLIENT_ID 안보입니다.
아무리 찾아봐도 안보이는데 뭐가 잘못된 것일까요?<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>API_KEY</key> <string>AIzaSyDrx2zMhB0rjE20rHntX6p1qG2Ya5y39JA</string> <key>GCM_SENDER_ID</key> <string>914949717898</string> <key>PLIST_VERSION</key> <string>1</string> <key>BUNDLE_ID</key> <string>com.archy712.bookreviewhome01.bookreviewHome01</string> <key>PROJECT_ID</key> <string>bookreview-home-01</string> <key>STORAGE_BUCKET</key> <string>bookreview-home-01.appspot.com</string> <key>IS_ADS_ENABLED</key> <false></false> <key>IS_ANALYTICS_ENABLED</key> <false></false> <key>IS_APPINVITE_ENABLED</key> <true></true> <key>IS_GCM_ENABLED</key> <true></true> <key>IS_SIGNIN_ENABLED</key> <true></true> <key>GOOGLE_APP_ID</key> <string>1:914949717898:ios:66b1d2b693a784b6029273</string> </dict> </plist>
-
해결됨[Bloc 응용] 실전 앱 만들기 (책 리뷰 앱) : SNS 로그인, Firebase 적용, Bloc 상태 관리, GoRouter
즐겨찾기 기능 질문 요청드립니다..
페이지 처음진입시 즐겨찾기 클릭하면정상적으로 별이 on 으로 바뀌게 되는데" 한번끄고 다시 키면 on으로 바뀌지않고 off 형태의 아이콘이되어있고 다시 뒤로갔다가 들어오면 정상적으로 on 으로 바껴있습니다 !!= 파이어베이스 db 상에는 데이터가 들어오지만상태가 바뀌지않아서 off 상태일때 10번누르면10번이 다 firebase db에 insert 되는현상이 나타납니다 ㅠㅠprofilePageactions: [ GestureDetector( onTap: () { var myUid = context.read<AuthenticationCubit>().state.user!.uid; context.read<UserProfileCubit>().followToggleEvent(myUid!); }, child: Padding( padding: const EdgeInsets.only(right: 20), child: BlocBuilder<UserProfileCubit,UserProfileState>( builder: (context,state) { var myUid = context.read<AuthenticationCubit>().state.user!.uid; var isFollowing = state.userModel?.followers?.contains(myUid) ?? false; return SvgPicture.asset(isFollowing ? 'assets/svg/icons/icon_follow_on.svg' :'assets/svg/icons/icon_follow_off.svg'); } ), ),user profile cubit void followToggleEvent(String myUid) async { if (state.userModel!.followers != null && state.userModel!.followers!.contains(myUid)) { // 즐겨찾기 취소 언팔 var result = await userRepository.followEvent(false,state.userModel!.uid!,myUid); if (result) { await _unfollow(myUid); } } else { // 즐겨 찾기 하기 var result = await userRepository.followEvent(true,state.userModel!.uid!, myUid); if (result) { await _follow(myUid); } } } _unfollow(myUid) async { emit( await state.copyWith( userModel: state.userModel!.copyWith( followers: List.unmodifiable( [...state.userModel!.followers!.where((targetUid) => targetUid != myUid)], ), ), ), ); } _follow(myUid) async { print(state.userModel!.followers); if (state.userModel!.followers == null) { // 최초 팔로워 대상 emit( await state.copyWith( userModel: state.userModel!.copyWith( followers: List.unmodifiable( [myUid], ), ), ), ); } else { // 다른사람이 이미 팔로워 한사람 emit( await state.copyWith( userModel: state.userModel!.copyWith( followers: List.unmodifiable( [ ...state.userModel!.followers!, uid ], ), ), ), ); } } }user-repositoryFuture<bool> followEvent(bool isFollow,String targetUid, String myUid) async { try { // 2 가지 업데이트 ( 트랜잭션 실행 필요 ) final batch = db.batch(); // Type1 . 상대방 팔로워에 내가 들어가는건다.. var targetUserDoc = await db.collection("users").where("uid", isEqualTo: targetUid).get(); UserModel targetUserInfo = UserModel.fromJson(targetUserDoc.docs.first.data()); var followers = targetUserInfo.followers ?? []; // 최초사람 if (isFollow) { followers.add(myUid); } else { followers.remove(myUid); } var targetRef = db.collection("users").doc(targetUserDoc.docs.first.id); batch.update(targetRef, {'followers': followers}); // Type1 . 내 팔로워에 상대방이 들어간다... var myUserDoc = await db.collection("users").where("uid", isEqualTo: myUid).get(); UserModel myUserInfo = UserModel.fromJson(myUserDoc.docs.first.data()); var followings = myUserInfo.followings ?? []; if (isFollow) { followings.add(targetUid); } else { followings.remove(targetUid); } var MyRef = db.collection("users").doc(myUserDoc.docs.first.id); batch.update(MyRef, {'followings': followings}); await batch.commit(); return true; } catch (e) { return false; } }
-
해결됨[Bloc 응용] 실전 앱 만들기 (책 리뷰 앱) : SNS 로그인, Firebase 적용, Bloc 상태 관리, GoRouter
리뷰작성 별점 문의
안녕하세요 개남님!! 다름이아니라 리뷰작성페이지에서 별점을 올려놓고 리뷰 입력할려고 텍스트 필드를 클릭하고 나면 별점이 0.00 으로 다시 되돌아가고 있습니다. 그리고 save 저장할대 값은 5.44 대로 잘 들어오고 있는 현상이 나타납니다 ㅠ..ㅠ리뷰 슬라이드바는 공유 해주신 dart 파일 그대로 사용하였구용 import 'package:book1/src/common/components/app_divider.dart'; import 'package:book1/src/common/components/review_slider_bar.dart'; import 'package:book1/src/common/model/naver_book_info.dart'; import 'package:book1/src/review/cubit/review_cubit.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/svg.dart'; import 'package:go_router/go_router.dart'; import '../../common/components/app_font.dart'; import '../../common/components/btn.dart'; class ReviewPage extends StatelessWidget { NaverBookInfo naverBookInfo; ReviewPage(this.naverBookInfo, {super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( leading: GestureDetector( onTap: context.pop, child: Padding( padding: const EdgeInsets.all(15.0), child: SvgPicture.asset('assets/svg/icons/icon_arrow_back.svg'), ), ), title: AppFont( "리뷰 작성", size: 18, ), centerTitle: true, ), body: Column( children: [ _HeaderBookInfo(naverBookInfo), AppDivider(), Expanded(child: _ReviewBox()), ], ), bottomNavigationBar: Padding( padding: EdgeInsets.only( left: 20, right: 20, top: 20, bottom: 20 + MediaQuery.of(context).padding.bottom), child: Btn( onTap: context.read<ReviewCubit>().save, text: '저장', ), ), ); } } class _ReviewBox extends StatelessWidget { _ReviewBox({super.key}); @override Widget build(BuildContext context) { return TextField( // 전체화면 텍스트필드 maxLines: null, decoration: const InputDecoration( border: InputBorder.none, hintText: "리뷰를 입력해주세요", contentPadding: EdgeInsets.symmetric(horizontal: 25), hintStyle: TextStyle( color: Color(0xff585858), ), ), onChanged: context.read<ReviewCubit>().changeReview, style: TextStyle(color: Colors.white), ); } } class _HeaderBookInfo extends StatelessWidget { final NaverBookInfo naverBookInfo; _HeaderBookInfo(this.naverBookInfo, {super.key}); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.all(25.0), child: Row( children: [ ClipRRect( borderRadius: BorderRadius.circular(7), child: SizedBox( width: 71, height: 106, child: Image.network( naverBookInfo.image ?? '', fit: BoxFit.fill, )), ), SizedBox( width: 15, ), Expanded( //어디 영역까지 사용할거냐 child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ AppFont( naverBookInfo.title ?? '', size: 16, fontWeight: FontWeight.bold, ), SizedBox( height: 5, ), AppFont( naverBookInfo.author ?? '', size: 12, color: Color(0xff878787), ), SizedBox( height: 10, ), ReviewSliderBar( onChange: context.read<ReviewCubit>().changeValue, ), ], ), ) ], ), ); } }
-
해결됨[Bloc 응용] 실전 앱 만들기 (책 리뷰 앱) : SNS 로그인, Firebase 적용, Bloc 상태 관리, GoRouter
플러터 바탕화면 빠진후 앱 진행시
안녕하세요 . 섹션7의 검색 라우터를 진행하다가 우연히 바탕화면에 들어갔다가 앱마크를 재생버튼이 아닌앱 마크를 클릭을 했더니 splash 화면에서 로딩중으로만 계속 되어있고print를 찍었더니 아예 App()에 있는 Gorouter 자체를 타지를 않는 현상이 생기고 있습니다.혹시 바탕화면 갔다가 다시 홈페이지 화면으로 들어가려고 하는데방법이 있을까 해서 글을 작성드렸습니다. 감사합니다 ㅠㅠ
-
해결됨[Bloc 응용] 실전 앱 만들기 (책 리뷰 앱) : SNS 로그인, Firebase 적용, Bloc 상태 관리, GoRouter
구글 로그인 관련 질문합니다.
로그아웃하고 난 뒤 다시 구글 계정 로그인 버튼을 누르면 전에 로그인 했던 계정으로 바로 넘어가는데구글 다른 계정으로 로그인 할 수 있는 방법이 있을까요?
-
해결됨[Bloc 응용] 실전 앱 만들기 (책 리뷰 앱) : SNS 로그인, Firebase 적용, Bloc 상태 관리, GoRouter
즐겨찾기 기능 구현 부분 오류 질문합니다.
즐겨찾기를 누르면 이러한 오류가 뜨는데 어디가 잘못된 걸까요?
-
해결됨[Bloc 응용] 실전 앱 만들기 (책 리뷰 앱) : SNS 로그인, Firebase 적용, Bloc 상태 관리, GoRouter
17강 진행중입니다..
강의 순서대로 따라하고 있는데구글 sns 등록하고 시뮬레이터 켜보니 Class 'StatelessElement' has no instance method 'read'.Receiver: Instance of 'StatelessElement'Tried calling: read<AuthenticationCubit>() 란 오류가 뜨네요 ㅠ찾아보니 밑 login_page 중 밑 read 부분인 것 같긴한데 정확히 모르겠습니다 ㅠWidget _appleLoginBtn(BuildContext, context) { return GestureDetector( onTap: context.read<AuthenticationCubit>().appleLogin(), child: Container(
-
해결됨[Bloc 응용] 실전 앱 만들기 (책 리뷰 앱) : SNS 로그인, Firebase 적용, Bloc 상태 관리, GoRouter
cloud Firestore 설정
FireStore Database에 들어가서 데이터베이스 생성하기 누르고 설정했는데 오류가 나더니이렇게 뜨네요,, 이런 경우 어떻게 해야 할까요,,?
-
해결됨[Bloc 응용] 실전 앱 만들기 (책 리뷰 앱) : SNS 로그인, Firebase 적용, Bloc 상태 관리, GoRouter
authentication_repository.dart 오류 질문합니다.
구글 로그인 버튼을 누르면 이런 오류가 뜨는데뭐가 잘못된 걸까요??
-
해결됨[Bloc 응용] 실전 앱 만들기 (책 리뷰 앱) : SNS 로그인, Firebase 적용, Bloc 상태 관리, GoRouter
signup_page.dart 오류 질문있습니다.
프로필 이미지 업로드 기능 개발 강의 듣는 중위와 같은 오류가 나는데어디 부분을 확인해야 할까요?
-
해결됨[Bloc 응용] 실전 앱 만들기 (책 리뷰 앱) : SNS 로그인, Firebase 적용, Bloc 상태 관리, GoRouter
개남님 초기 페이지 연결하기 부분 질문입니다!
개남님 좋은 강의 감사합니다. 현재 초기 페이지 연결하기까지 진행했습니다. 조금 오류가 있는 것 같은데 순수하게 궁금해서 여쭙니다! main.dart에서 AppDataLoadCubit을 lazy:false로 뒀잖아요? 그럼 앱을 처음 다운 받았을 때 init page가 보여지고 lazy가 false이기 때문에 스플래시 화면에 도달하기 전 이미 데이터를 로드해서, 시작하기 버튼을 눌러 스플래시 화면에 도달했을 때면, 바로 로그인 체크 중 입니다..가 보여야 하는 것 아닌가요?? 제 에뮬레이터에는 데이터 로드 중 입니다..가 보이길래 영상을 다시 돌려봤는데 개남님도 같은 현상이십니다. 그리고 시작하기 버튼을 통해 init -> splash에 도달했을 때 새로고침하지 않으면 데이터 로드 중 입니다..에서 로그인 확인 중 입니다..로 바뀌지 않습니다. 단순 오류인가 해서 앱을 지워 hydrated bloc을 초기화하고 다시 확인해 보았지만 같은 현상이 일어납니다.
-
해결됨[Bloc 응용] 실전 앱 만들기 (책 리뷰 앱) : SNS 로그인, Firebase 적용, Bloc 상태 관리, GoRouter
개남님 equatable에 대한 보충 설명 좀 부탁드릴게요 !
개남님 좋은 강의 감사합니다. equatable을 계속 사용하셔서 알아봤는데 잘 이해되지 않습니다. 클래스 인스턴스 비교에 활용된다는 것과, 그 원리는 이해했는데, 모델 클래스랑 관련이 있나요??
-
해결됨[Bloc 응용] 실전 앱 만들기 (책 리뷰 앱) : SNS 로그인, Firebase 적용, Bloc 상태 관리, GoRouter
Json 데이터가 불완전할때는 어떻게 해결을 하시나요?
선생님 실무에서 받는 JSON 데이터가 가끔은 필요한 포맷으로 딱 떨어지지 않을때가 있는데 이럴때 실무에서는 어떻게 해결을 하시나요? 이번에 북 리뷰에도 어떤 책들의 저자들은(길거나, 영문일때 등) ^ 이런 표시가 있어서 사용 환경을 약간 저해하는 듯 싶어서 해결을 하고 싶은데 어떻게 해야할지 감을 못잡겠네요 ㅠ
-
해결됨[Bloc 응용] 실전 앱 만들기 (책 리뷰 앱) : SNS 로그인, Firebase 적용, Bloc 상태 관리, GoRouter
최근 작성 리뷰 Top10 기능 구현 강의 overflow 오류
최근 작성 리뷰 Top10 기능 구현강의 에서 타이틀이랑 작가부분을 퍼블리싱 했는데 오버플로우 오류가 뜨네요 ㅠㅠ 왜 생기는 거고 어떻게 해결을 해야 하나요? 혹시 선생님의 시뮬레이션 기기가 아이폰 pro max 여서 안생겼고, 저는 아이폰 14여서 생기는 건가요? 그러면 유저들이 다양한 디바이스를 쓸텐데 오버플로우 오류를 해결 할 수 있는 방법이 있을까요?ㅠㅠ
-
해결됨[Bloc 응용] 실전 앱 만들기 (책 리뷰 앱) : SNS 로그인, Firebase 적용, Bloc 상태 관리, GoRouter
애플 개발자 홈페이지 관련
파이어베이스로 애플아이디 로그인을 연동하는 과정에 있는데요.혹시 애플 개발자 멤버십을 구입해야 식별자 등록 및 KEY 생성과 같은 여러가지 리소스를 이용할 수 있는건가요?
-
해결됨[Bloc 응용] 실전 앱 만들기 (책 리뷰 앱) : SNS 로그인, Firebase 적용, Bloc 상태 관리, GoRouter
선생님 리뷰슬라이더 강의 요청 드려도 될까요? ㅠㅠ
아무래도 플러터가 주로 하는게 프론트 단이다보니 오히려 이런 꿀 위젯들 만드는 거가 되게 중요할 때가 업무중에 많더라구요 ㅠㅠ 그래서 혹시 미니 강의라도 리뷰 슬라이더 어떻게 만드셨는지 강의해 주실 수 있으실까요?ㅠㅠ
-
해결됨[Bloc 응용] 실전 앱 만들기 (책 리뷰 앱) : SNS 로그인, Firebase 적용, Bloc 상태 관리, GoRouter
널 체크
개남님 페이징처리 하는 부분에서 이런 오류가 생겼네요. 계속 여러번 확인해봤는데 개남님의 코드와 제 코드의 차이점은 잘 모르겠습니다...혹시 어떤 이유인지 알 수 있을까요?감사합니다!https://github.com/Bamschool/book_review :ui/hooks.dart:202:13) #9 _ChannelCallba<…> Reloaded 1 of 1754 libraries in 196ms (compile: 36 ms, reload: 79 ms, reassemble: 64 ms). [VERBOSE-2:dart_vm_initializer.cc(41)] Unhandled Exception: Null check operator used on a null value #0 SearchBookCubit.search package:review_book/…/cubit/search_book_cubit.dart:30 #1 EditableTextState._finalizeEditing package:flutter/…/widgets/editable_text.dart:3079 #2 EditableTextState.performAction package:flutter/…/widgets/editable_text.dart:2910 #3 TextInput._handleTextInputInvocation package:flutter/…/services/text_input.dart:1870 #4 TextInput._loudlyHandleTextInputInvocation package:flutter/…/services/text_input.dart:1753 #5 MethodChannel._handleAsMethodCall package:flutter/…/services/platform_channel.dart:547 #6 MethodChannel.setMethodCallHandler.<anonymous closure> package:flutter/…/services/platform_channel.dart:540 #7 _DefaultBinaryMessenger.setMessageHandler.<anonymous closure> package:flutter/…/services/binding.dart:567 #8 _invoke2 (dart:ui/hooks.dart:202:13) #9 _ChannelCallba<…>
-
해결됨[Bloc 응용] 실전 앱 만들기 (책 리뷰 앱) : SNS 로그인, Firebase 적용, Bloc 상태 관리, GoRouter
데이터 저장2
안녕하세요 개남님 개남님이 만들어주신 코드와 제가 가지고 있던 코드랑 같이 활용을 해보려고 했는데 기존에 있던 코드가 작동을 안 하는데 혹시. 개남님이 만드신 Authrepository를 사용안하면 기존에 있던 name이나 Uid를 인식을 못 해서 안 불러지는건가요?--추가--신기한건[VERBOSE-2:dart_vm_initializer.cc(41)] Unhandled Exception: Bad state: cannot get a field on a DocumentSnapshotPlatform which does not exist 이런식으로 에러가 뜨네요... 흠.. 분명 name은 존재한다고 뜨긴하는데.. (개남님이 만드신 방식으로 해야만 뜹니다)(추가)이런식으로 해봤더니 기존의 구글 name이 뜨네요.음 Authrepository의 cubit에서 인식하는 name은 우리가 회원가입에서 입력한 이름이고제가 만든 코드에서 인식하는 name은 구글 기존의 이름으로 뜹니다. 이유가 뭘까요? 감사합니다! void _nameEvent(NameEvent event, Emitter<HomePageState> emitter) async { String uid = FirebaseAuth.instance.currentUser!.uid; DocumentSnapshot document = await FirebaseFirestore.instance.collection('users').doc(uid).get(); String userName = document['name']; int level = document['level']; //여기는 기존의 bloc입니다 //이 아래는 이렇게하니까 우리가 추가한 네임이 아니라 기존의 구글 네임이 뜨게 되는 코드입니다. void _nameEvent(NameEvent event, Emitter<HomePageState> emitter) async { UserModel? userModel; final user = await _authenticationRepository.user.first; final userName = user?.name ?? 'Unknown'; // 기본값 설정 print("유저의 이름은 $user"); print("유저의 이름은 $userName"); emit(state.copyWith( name: userName, )); // 기존의 Firestore에서 사용자 정보를 가져오는 코드... String uid = FirebaseAuth.instance.currentUser!.uid; DocumentSnapshot document = await FirebaseFirestore.instance.collection('users').doc(uid).get(); int level = document['level']; print(user); print(userName); emitter(state.copyWith( level: level, name: userName, )); }
-
해결됨[Bloc 응용] 실전 앱 만들기 (책 리뷰 앱) : SNS 로그인, Firebase 적용, Bloc 상태 관리, GoRouter
클라우드 스토어
안녕하세요 개남님 가입하기를 여러번 누르면 이렇게 기존에있던 데이터에서 변경하는 것이 아니라 이런식으로 바뀌는데 이것말고 기존에있던 것에서 덮는 방식은 없을까요?
-
해결됨[Bloc 응용] 실전 앱 만들기 (책 리뷰 앱) : SNS 로그인, Firebase 적용, Bloc 상태 관리, GoRouter
redirect
안녕하세요 개남님개남님처럼 로그인한후에 Unknown에서 unauth로 가면서 signup으로 가야하는데 저는 unauth에서 Auth로 가면서 그냥 로그인 페이지에 머무르는데.. 이유가 뭘까요? 감사합니다.(애플로그인은 아직 구현 못하고 구글로그인만 구현을 했습니다) https://github.com/Bamschool/book_review