【Flutter】Firebaseにデータが登録できない問題の解決方法

# 【Flutter】Firebaseにデータが登録できない問題の解決方法

## 概要
FlutterアプリでFirebase Authenticationでのユーザー登録は成功するが、Firestoreへのデータ保存が失敗する問題に遭遇しました。
エラーメッセージは `[cloud_firestore/unknown] Unable to establish connection on channel.` でした。

## 環境
- **フレームワーク**: Flutter
- **言語**: Dart
- **Firebase**: Firebase Auth + Cloud Firestore
- **プラットフォーム**: Android
- **開発環境**: Android Studio

## 発生した問題

### エラーログ
```
I/flutter ( 6338): メールアドレス: 777@gmail.com, パスワード: 777777
I/FirebaseAuth( 6338): Creating user with 777@gmail.com with empty reCAPTCHA token
D/FirebaseAuth( 6338): Notifying id token listeners about user ( iS1jVrC3vieqYITG6Wu4WA2yoMu2 ).
I/flutter ( 6338): ユーザーUID: iS1jVrC3vieqYITG6Wu4WA2yoMu2
I/flutter ( 6338): Firestoreエラー: [cloud_firestore/unknown] Unable to establish connection on channel.
I/flutter ( 6338): 登録成功: iS1jVrC3vieqYITG6Wu4WA2yoMu2
```

### 症状
- Firebase Authenticationでのユーザー作成は成功
- ユーザーUIDも正常に取得
- しかし、Firestoreへのデータ保存で接続エラーが発生
- Firebase Consoleにコレクションが作成されない

## 原因
**AndroidManifest.xmlにインターネット権限が不足していた**

Android アプリがFirestoreに接続するためには、明示的にインターネット権限を宣言する必要がありますが、これが抜けていました。

## 解決方法

### 1. AndroidManifest.xmlの修正

`android/app/src/main/AndroidManifest.xml` に以下の権限を追加：

```xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- インターネット権限を追加 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    
    <application
        android:label="todo"
        android:name="${applicationName}"
        android:icon="@mipmap/ic_launcher">
        <!-- 以下既存のコード -->
    </application>
</manifest>
```

### 2. 追加した権限の説明
- `INTERNET`: インターネット接続に必要
- `ACCESS_NETWORK_STATE`: ネットワーク状態の確認に必要（推奨）

### 3. Firestoreコードの改善

エラーハンドリングとデバッグ用ログを追加：

```dart
try {
  final User user = userCredential.user!;
  print("ユーザーUID: ${user.uid}");
  
  // Firestoreにデータを保存
  await FirebaseFirestore.instance
      .collection('users')
      .doc(user.uid)
      .collection('todos')
      .doc('0')
      .set({
        "item": "初回TODO", 
        "done": false,
        "createdAt": FieldValue.serverTimestamp(),
      });
  
  print("Firestoreにデータを保存しました");
} catch (firestoreError) {
  print("Firestoreエラー: $firestoreError");
}
```

## 注意点

### 1. アプリの再起動が必要
AndroidManifest.xmlを変更した場合は、**必ずアプリを完全に再起動**する必要があります。
ホットリロードでは権限の変更は反映されません。

### 2. awaitキーワードの重要性
Firestoreの書き込み処理は非同期なので、`await`キーワードを忘れずに付けましょう：

```dart
// ❌ 間違い
FirebaseFirestore.instance.collection('users').doc(uid).set(data);

// ✅ 正しい
await FirebaseFirestore.instance.collection('users').doc(uid).set(data);
```

### 3. Firestoreセキュリティルールの確認
データが保存されない場合は、Firestoreのセキュリティルールも確認してください：

```javascript
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // 認証済みユーザーのみアクセス可能
    match /{document=**} {
      allow read, write: if request.auth != null;
    }
  }
}
```

## まとめ
Firebase Authenticationは成功するがFirestoreに接続できない場合は、まずAndroidManifest.xmlのインターネット権限を確認しましょう。
この権限が不足していることが原因のケースが多いです。

権限を追加後は必ずアプリを完全に再起動し、エラーハンドリングを追加してデバッグを行うことで、問題を特定しやすくなります。

## 参考
- [Flutter Firebase公式ドキュメント](https://firebase.flutter.dev/)
- [Android権限について](https://developer.android.com/guide/topics/permissions/overview)