flutter

[Flutter 기초] Flutter와 Firestore 연동하기(Android studio)

j2kb 2020. 4. 11. 14:02
반응형

이 글은 Youtube Flutter강의를 번역하였습니다.

기본적으로 영상의 내용과 같습니다.

다만 2년 전 영상이라 그런지 그대로 따라할 경우 Multidex와 관련한 오류가 발생해 빌드가 되지 않는데 그 부분만 추가하였습니다.

언젠가 다시 Firestore를 활용해 앱을 만들 때 영상을 다시 볼 수 없으니 해야할 것들만 딱 정리하도록 하겠습니다. 

 

[참고 내용]

Multidex에서 dex는 Dalvik Executable의 약어입니다. android 앱은 기본적으로 Simple하고 Small하게 만들어지도록 되어있어서 65,536개의 Method들만 사용할 수 있도록 되어있다고 합니다. Method들의 수가 이 숫자를 넘어갈 경우 Multidex 오류가 발생한다고 합니다. 이 경우 앱 수준의 build.gradle에서 multiDexEnabled true를 바꿔주지 않으면 iOS앱은 잘 되는데 Android앱은 빌드가 안되는 오류가 발생합니다.

 

 

1, Firestore 저장소 만들기

firebase에 접속하여 프로젝트를 추가합니다

 

 

2. Android studio에서 flutter 앱 만들기

이름은 jk2b_test로 만들었습니다

패키지 이름은 com.jk2b.jk2btest로 만들었습니다. 추후에 Firebase에서 앱을 등록할 때 사용합니다.

따로 적지 않아도 [app]->[src]->[main] 밑의 AndroidManifest.xml에서 확인할 수 있습니다

 

3. Firebase에 iOS와 Android 앱 추가하기

저는 jk2b-test로 만들었습니다

앱은 여러개를 추가할 수 있습니다. 먼저 iOS를 추가하겠습니다

앱 등록 후 구성파일을 다운로드 합니다. 그리고 xcode를 엽니다(Runner.xcworkspace)

방금 다운 받은 plist파일을 넣어줍니다.

 

다음 Android를 추가합니다

똑같이 구성파일을 다운로드 받고 몇가지 코드를 넣어줍니다. 프로젝트 수준의 build.gradle에 dependencies를 추가해주고

classpath 'com.google.gms:google-services:4.3.3'

앱 수준의 build.gradle에 apply 구문도 추가해줍니다.

apply plugin: 'com.google.gms.google-services'

defaulfConfig 부분에 multiDexEnabled 설정도 넣어줍니다

defaultConfig {
  // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
  applicationId "com.jk2b.jk2btest"
  minSdkVersion 16
  targetSdkVersion 28
  versionCode flutterVersionCode.toInteger()
  versionName flutterVersionName
  testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
  multiDexEnabled true
}

 

 

4. Firebase에 Database 만들고 규칙 수정

보통 테스트 모드로 만드는데 저는 별 이유 없이 프로덕션 모드에서 시작하였습니다. 그래서 규칙을 수정해주어야 나중에 접근이 가능합니다. 데이터베이스 지역은 일본에 있는 동아시아로 하였습니다.(아무래도 거리가 가까우니 미국보단 빠를 것 같아서)

5. 데이터 추가

지금 만들앱에서는 문서이름은 필요가 없고 컬렉션 이름은 앱에서 알고 있어야합니다.

컬렉션은 Test로 만들고 문서 이름은 랜덤하게 생성해주는 기능을 사용했습니다.

필드에 name과 votes를 추가해줍니다

6. 코드 작성

이제 widget을 만들고 Firebase를 가져오는 코드를 만들어보겠습니다

 

main.dart를 엽니다.

cloud_firestore.dart를 import하고 firestore instance를 가져옵니다.

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';

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


class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Firestore firestore = Firestore.instance;
  @override

  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Band Name Test",
      theme: ThemeData.dark(),
      home: const MyHomePage(title: 'Band names'),
    );
  }
}

 

화면에 보여줄 위젯을 생성합니다

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: StreamBuilder(
          stream: Firestore.instance.collection('Test').snapshots(),
          builder: (context, snapshot) {
            if (!snapshot.hasData) return const Text('Loading...');
            return ListView.builder(
              itemExtent: 80.0,
              itemCount: snapshot.data.documents.length,
              itemBuilder: (context, index) =>
                  _buildListItem(context, snapshot.data.documents[index]),
            );
          }
      ),
    );
  }
}

 

_buildListItem 메소드를 만들면 끝!

  Widget _buildListItem(BuildContext context, DocumentSnapshot document) {
    return ListTile(
      title: Row(
        children: <Widget>[
          Expanded(
            child: Text(
              document['name'],
              style: Theme.of(context).textTheme.headline,
            ),
          ),
          Container(
            decoration: const BoxDecoration(
              color: Color(0xffddddff),
            ),
            padding: const EdgeInsets.all(10.0),
            child: Text(
              document['votes'].toString(),
              style: Theme.of(context).textTheme.display1,
            ),
          )
        ],
      ),
      onTap: () {
        print("should increase votes here.");
        document.reference.updateData({
          'votes': document['votes'] + 1
        });
      },
    );
  }

 

 

[관련 링크]

https://www.youtube.com/watch?v=DqJ_KjFzL9I&t=597s

Multidex관련

https://www.linkedin.com/pulse/android-multidex-how-deal-chris-sullivan

반응형