[flutter] Firebase Firestore와 플러터를 이용한 날씨 알리미 애플리케이션 만들기

안녕하세요! 이번에는 Flutter와 Firebase Firestore를 이용하여 날씨 알리미 애플리케이션을 만들어보려고 합니다.

목차

  1. Firebase Firestore란?
  2. Firebase Firestore 설정하기
  3. 플러터 프로젝트 생성하기
  4. FirebaseAuth와 Firestore 연동하기
  5. 날씨 데이터 가져오기
  6. 애플리케이션 화면 구성하기
  7. 시간별 날씨 예보 표시하기
  8. 사용자 위치 기반 날씨 정보 가져오기
  9. Firestore에 날씨 정보 저장하기
  10. 알림 기능 추가하기
  11. 마무리하며

1. Firebase Firestore란?

Firebase Firestore는 Firebase의 실시간 데이터베이스 서비스 중 하나입니다. Firestore는 NoSQL 데이터베이스로 JSON 형식의 데이터를 저장하고 동기화하는 기능을 제공합니다.

2. Firebase Firestore 설정하기

Firebase Console에 접속하여 새로운 프로젝트를 생성한 후, Firestore 데이터베이스를 활성화합니다. 애플리케이션의 패키지 이름을 등록하고, google-services.json 파일을 다운로드하여 프로젝트에 추가합니다.

3. 플러터 프로젝트 생성하기

플러터를 이용하여 새로운 프로젝트를 생성합니다. flutter create 명령어로 프로젝트를 생성한 후, 필요한 종속성을 추가합니다.

flutter create weather_app
cd weather_app

4. FirebaseAuth와 Firestore 연동하기

FirebaseAuth와 Firestore를 사용하기 위해 firebase_authcloud_firestore 패키지를 프로젝트에 추가합니다. pubspec.yaml 파일에 다음과 같이 종속성을 추가합니다.

dependencies:
  flutter:
    sdk: flutter
  firebase_auth: ^0.20.1
  cloud_firestore: ^0.16.0

pubspec.yaml 파일을 업데이트한 후, 패키지를 다운로드합니다.

flutter pub get

Firebase 초기화 코드를 main.dart 파일에 추가합니다.

import 'package:firebase_core/firebase_core.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

5. 날씨 데이터 가져오기

OpenWeatherMap API를 이용하여 날씨 정보를 가져옵니다. http 패키지를 사용하여 API 요청을 보내고, 응답을 받아 처리합니다.

import 'package:http/http.dart' as http;
import 'dart:convert';

Future<WeatherData> fetchWeatherData(String cityName) async {
  final apiKey = 'YOUR_API_KEY';
  final url =
      'https://api.openweathermap.org/data/2.5/weather?q=$cityName&appid=$apiKey';
  final response = await http.get(Uri.parse(url));

  if (response.statusCode == 200) {
    return WeatherData.fromJson(jsonDecode(response.body));
  } else {
    throw Exception('Failed to load weather data');
  }
}

class WeatherData {
  final String cityName;
  final double temperature;
  // ...
  
  factory WeatherData.fromJson(Map<String, dynamic> json) {
    return WeatherData(
      cityName: json['name'],
      temperature: json['main']['temp'],
      // ...
    );
  }
}

6. 애플리케이션 화면 구성하기

플러터를 사용하여 애플리케이션의 화면을 구성합니다. 필요한 위젯을 추가하고, 날씨 데이터를 표시합니다.

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    home: WeatherApp(),
  ));
}

class WeatherApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('날씨 알리미'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              '현재 날씨',
              style: TextStyle(
                fontSize: 24,
                fontWeight: FontWeight.bold,
              ),
            ),
            // 날씨 정보 표시
            // ...
          ],
        ),
      ),
    );
  }
}

7. 시간별 날씨 예보 표시하기

날씨 예보를 표시하기 위해 ListView와 ListTile을 사용합니다. 각각의 ListTile에는 시간과 날씨 정보를 표시합니다.

class WeatherApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // AppBar, body 생략
      
      body: ListView.builder(
        itemCount: forecast.length,
        itemBuilder: (ctx, i) {
          return ListTile(
            title: Text(forecast[i].time),
            subtitle: Text(forecast[i].weather),
          );
        },
      ),
    );
  }
}

class ForecastData {
  final String time;
  final String weather;
  
  ForecastData({this.time, this.weather});
}

List<ForecastData> forecast = [
  ForecastData(time: '12:00 PM', weather: '맑음'),
  ForecastData(time: '3:00 PM', weather: '구름 조금'),
  // ...
];

8. 사용자 위치 기반 날씨 정보 가져오기

사용자의 위치를 가져오기 위해 geolocator 패키지를 사용합니다. 위치 정보를 가져온 후, OpenWeatherMap API로 날씨 정보를 가져옵니다.

import 'package:geolocator/geolocator.dart';

Future<Position> getCurrentLocation() async {
  Position position = await Geolocator.getCurrentPosition(
      desiredAccuracy: LocationAccuracy.high);
  return position;
}

Position currentPosition;

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  getCurrentLocation().then((position) {
    currentPosition = position;
    runApp(MaterialApp(home: WeatherApp()));
  });
}

9. Firestore에 날씨 정보 저장하기

Firebase Firestore를 사용하여 날씨 정보를 저장합니다. cloud_firestore 패키지를 사용하여 Firestore에 데이터를 추가합니다.

import 'package:cloud_firestore/cloud_firestore.dart';

Future<void> saveWeatherData(WeatherData weatherData) {
  CollectionReference weatherCollection =
      FirebaseFirestore.instance.collection('weather');

  return weatherCollection.add({
    'cityName': weatherData.cityName,
    'temperature': weatherData.temperature,
    // ...
  })
      .then((value) => print("Weather data added"))
      .catchError((error) => print("Failed to add weather data: $error"));
}

10. 알림 기능 추가하기

알림 기능을 추가하여 특정 날씨 조건을 충족할 때 사용자에게 알림을 보냅니다. flutter_local_notifications 패키지를 사용하여 알림을 설정하고 보내는 기능을 구현합니다.

import 'package:flutter_local_notifications/flutter_local_notifications.dart';

Future<void> showNotification(String weather) async {
  FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
      FlutterLocalNotificationsPlugin();

  var initializationSettingsAndroid =
      AndroidInitializationSettings('app_icon');

  var initializationSettingsIOS = IOSInitializationSettings();

  var initializationSettings = InitializationSettings(
      android: initializationSettingsAndroid, iOS: initializationSettingsIOS);

  await flutterLocalNotificationsPlugin.initialize(initializationSettings);

  var androidPlatformChannelSpecifics = AndroidNotificationDetails(
    'weather_notifications',
    'Weather Notifications',
    'Notification channel for weather alerts',
    importance: Importance.max,
    priority: Priority.high,
    showWhen: false,
  );

  var iOSPlatformChannelSpecifics = IOSNotificationDetails();

  var platformChannelSpecifics = NotificationDetails(
      android: androidPlatformChannelSpecifics,
      iOS: iOSPlatformChannelSpecifics);

  await flutterLocalNotificationsPlugin.show(
    0,
    '날씨 알림',
    '오늘은 $weather입니다',
    platformChannelSpecifics,
  );
}

11. 마무리하며

이번에는 Flutter와 Firebase Firestore를 이용하여 날씨 알리미 애플리케이션을 만들어보았습니다. Firebase를 사용하면 강력한 데이터베이스 기능을 활용하여 애플리케이션을 개발할 수 있습니다. 알림 기능을 추가하면 사용자에게 실시간으로 날씨 정보를 알려줄 수 있습니다.

더 자세한 내용은 Flutter 공식 문서Firebase 공식 문서를 참고해주세요.