프로필 수정 관련 트러블 슈팅

김동연·2025년 6월 9일

개발기록일지(Flutter)

목록 보기
17/32

오류 요약

오류 메시지:

lib/pages/user_profile_page/widgets/profile_image_widget:43:51: Error: Too many positional arguments: 0 allowed, but 2 found.
Try removing the extra positional arguments.

위치:

final downloadUrl = await uploadProfileImage(widget.userId, imageFile);

문제 원인

1. 함수 정의 방식과 호출 방식 불일치

  • uploadProfileImage 함수는 named parameters (이름 있는 인자) 방식을 사용하고 있음:

    Future<void> uploadProfileImage({
      required String userId,
      required File imageFile,
    })
  • 그런데 함수 호출 시에는 positional parameters (순서 인자) 방식으로 잘못 호출:

    // 잘못된 예
    uploadProfileImage(widget.userId, imageFile); // ❌

    이 호출 방식은 "순서대로 인자를 전달"하는 방식인데, 이 함수는 이를 허용하지 않음.


해결 과정

1. 함수 호출을 named parameters 방식으로 수정

// 올바른 방식 
await uploadProfileImage(
  userId: widget.userId,
  imageFile: imageFile,
);

이렇게 작성하면 uploadProfileImage 함수 정의에 맞게 인자를 전달하므로 오류가 해결됨.


최종 결과

  • 컴파일 오류 해결: named parameter 방식으로 수정함으로써 빌드가 정상적으로 완료됨.
  • 이미지 업로드 정상 작동: 선택된 이미지를 Firebase Storage에 업로드하고, 해당 URL이 Firestore의 users/{userId} 문서의 photoUrl 필드에 저장됨.
  • 화면 반영 정상: userProfileProvider는 StreamProvider 기반이기 때문에 Firestore에 변경이 반영되면 자동으로 UI가 최신 상태로 갱신됨.

  • Dart에서 named parameters를 사용하는 함수는 호출 시 반드시 키워드를 사용해야 함.
  • 함수 정의를 잘 모를 땐 Ctrl (Cmd) + 클릭으로 선언부로 이동하여 확인 가능.
  • Flutter에서 실수로 positional/named 혼용 오류가 많이 발생하므로 IDE 경고를 잘 확인하는 것이 중요.

2. 트러블슈팅: image_picker 오류

오류 메시지 요약:

PlatformException(channel-error, Unable to establish connection on channel: "dev.flutter.pigeon.image_picker_ios.ImagePickerApi.pickImage".)

원인:

  • iOS에서 image_picker 플러그인이 채널 연결에 실패
  • 특히 시뮬레이터에서 image_picker는 카메라 사용 불가
  • 또는 iOS 권한 설정 미비

해결 방법:

iOS 설정 수정 (필수)

ios/Runner/Info.plist에 아래 추가:

<key>NSPhotoLibraryUsageDescription</key>
<string>프로필 사진을 선택하기 위해 사진 접근이 필요합니다.</string>
<key>NSCameraUsageDescription</key>
<string>프로필 사진을 촬영하기 위해 카메라 접근이 필요합니다.</string>

iOS 시뮬레이터가 아닌 실제 기기에서 테스트

  • 시뮬레이터는 ImageSource.camera 사용 시 실패합니다
  • 가능하면 ImageSource.gallery로만 테스트하세요

패키지 설치 확인

flutter pub add image_picker

그리고 반드시 실행:

flutter clean
flutter pub get

1, 2는 잘되어었지만, 3에 해당하는 ios pod 초기화 후 클린빌드를 안했었음.


3. 현재 프로필 수정 및 스토리지 저장 방식 요약

흐름 요약:

  1. 사용자가 프로필 이미지를 탭함

  2. image_picker로 갤러리에서 이미지 선택

  3. 선택된 이미지가 Firebase Storage에 업로드

    • 경로: users/{userId}/profile.jpg
    • 덮어쓰기됨 (기존 이미지 삭제됨)
  4. 업로드 완료 후 다운로드 URL을 가져옴

  5. Firestore의 users/{userId} 문서에 photoUrl 필드를 URL로 갱신

  6. UI는 StreamProvider로 실시간 반영됨

구조:

Firebase Storage:
├── users/
│   └── {userId}/
│       └── profile.jpg  ← 항상 이 경로 하나만 유지

Firestore:
├── users/
│   └── {userId} → { photoUrl: "https://firebasestorage.googleapis.com/..." }

0개의 댓글