전체 과정 설명 및 관련 페이지별 수정 사항
아래는 닉네임 변경 시 친구 목록에 알림 메시지가 전송되도록 구현한 전체 과정과 관련된 각 페이지에서 어떤 부분이 수정되었는지에 대한 설명입니다.
1. notification_service.dart - 알림 관리 서비스
- 역할: 친구 기기에 알림 메시지를 전송하고, 알림 메시지를 로컬 저장소에 저장하는 기능을 제공합니다.
- 수정 사항:
- sendNicknameChangeNotification: 닉네임 변경 시 알림 메시지를 전송하는 메서드.
- storeNotification: 받은 알림 메시지를 로컬 저장소에 저장하는 메서드.
- getStoredNotifications: 저장된 알림 메시지를 불러오는 메서드.
- clearNotifications: 저장된 알림 메시지를 모두 삭제하는 메서드.
2. sharedpreference.dart - 로컬 저장소 관리
- 역할: 알림 메시지를 로컬 저장소에 저장하고 불러오는 기능을 제공합니다.
- 수정 사항:
- storeNotification: 알림 메시지를 SharedPreferences에 저장.
- getStoredNotifications: SharedPreferences에서 저장된 알림 메시지 목록을 불러옴.
- clearNotifications: 저장된 알림 메시지를 삭제.
3. profile_provider.dart - 프로필 관련 데이터 관리
- 역할: 닉네임 변경과 관련된 데이터를 관리하고, 닉네임 변경 시 친구들에게 알림 메시지를 보내는 기능을 담당합니다.
- 수정 사항:
- updateNickname: 닉네임을 변경하고, 알림을 전송하는 로직을 추가.
- notifyFriendsAboutNicknameChange: 닉네임이 변경된 후 친구들에게 알림을 전송하는 메서드.
- getFriendIds: 친구 목록을 불러오는 메서드 (이 메서드는 실제 구현할 때 오류가 발생할 수 있습니다).
4. nickname_change.dart - 닉네임 변경 화면
- 역할: 사용자가 닉네임을 변경할 수 있는 UI를 제공합니다.
- 수정 사항:
- onPressed 이벤트 핸들러에서 닉네임 변경 요청을 ProfileProvider로 전달하고, 닉네임이 변경된 후 알림을 전송하도록 수정.
5. user_provider.dart - 사용자 관리
- 역할: 사용자 정보 관련 데이터를 관리하고, 데이터베이스와의 상호작용을 담당합니다.
- 수정 사항:
- 닉네임 변경 후 알림 메시지를 친구들에게 전송하는 로직이 추가되었습니다.
순차적으로 사용된 클래스들 정리
- NotificationService (notification_service.dart)
- 알림 메시지를 전송하고 로컬에 저장하는 기능을 제공.
- SharedPreferences (sharedpreference.dart)
- 로컬 저장소에 알림 메시지를 저장하고 불러오는 기능을 제공.
- ProfileProvider (profile_provider.dart)
- 프로필과 관련된 데이터를 관리하며, 닉네임 변경 시 알림을 전송.
- NicknameChange (nickname_change.dart)
- 사용자가 닉네임을 변경할 수 있는 UI 제공 및 닉네임 변경 이벤트 처리.
- UserProvider (user_provider.dart)
- 사용자 정보를 관리하고 친구 목록과 관련된 기능을 담당.
이 과정에서 닉네임 변경 시 친구에게 알림을 보내고, 알림을 로컬에 저장하여 사용자가 나중에 알림을 확인할 수 있도록 하는 기능을 구현했습니다. 각 단계별로 페이지를 수정하며 위의 클래스들을 연동하여 기능을 완성했습니다.
1. notification_service.dart
이 클래스는 Flutter Local Notifications와 SharedPreferences를 사용하여 알림을 생성하고 저장하는 역할을 담당합니다.
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:shared_preferences/shared_preferences.dart';
class NotificationService {
static final FlutterLocalNotificationsPlugin _notificationsPlugin =
FlutterLocalNotificationsPlugin();
static Future<void> sendNicknameChangeNotification(
{required String oldNickname, required String newNickname}) async {
// 알림 생성
const AndroidNotificationDetails androidDetails =
AndroidNotificationDetails(
'nickname_change_channel',
'Nickname Change',
channelDescription: '닉네임 변경 알림',
importance: Importance.max,
priority: Priority.high,
);
const NotificationDetails platformDetails =
NotificationDetails(android: androidDetails);
// 알림 전송
await _notificationsPlugin.show(
0,
'닉네임 변경',
'$oldNickname에서 $newNickname으로 닉네임이 변경되었습니다.',
platformDetails,
);
// 로컬 저장소에 메시지 저장
final prefs = await SharedPreferences.getInstance();
List<String> notifications =
prefs.getStringList('notifications') ?? [];
notifications.add('$oldNickname에서 $newNickname으로 닉네임이 변경되었습니다.');
await prefs.setStringList('notifications', notifications);
}
// 저장된 알림 가져오기
static Future<List<String>> getStoredNotifications() async {
final prefs = await SharedPreferences.getInstance();
return prefs.getStringList('notifications') ?? [];
}
// 알림 지우기
static Future<void> clearNotifications() async {
final prefs = await SharedPreferences.getInstance();
await prefs.remove('notifications');
}
}
2. profile_provider.dart
이 클래스는 프로필 관련 데이터를 관리하며, 닉네임 변경 시 친구들에게 알림을 보내는 역할을 수행합니다.
import 'package:flutter/foundation.dart';
import 'package:todomate/models/signup_model.dart';
import 'package:todomate/service/notification_service.dart';
class ProfileProvider with ChangeNotifier {
final DatabaseHelper _dbHelper = DatabaseHelper(); // DB 불러옴
String? _nickname;
String _avatarPath = 'asset/image/avata_1.png'; // 기본 아바타 경로로 초기화
bool _isNicknameLoaded = false; // 닉네임 로딩 상태 추가
int _friendCount = 0;
String? get nickname => _nickname;
String get avatarPath => _avatarPath;
bool get isNicknameLoaded => _isNicknameLoaded;
int get friendCount => _friendCount;
Future<void> loadNickname(String loginId) async {
if (_isNicknameLoaded) return;
_nickname = await _dbHelper.getNickname(loginId);
if (_nickname == null || _nickname!.isEmpty) {
_nickname = loginId;
await _dbHelper.updateNickname(loginId, _nickname!);
}
_isNicknameLoaded = true;
notifyListeners();
}
Future<void> updateNickname(String loginId, String newNickname) async {
String oldNickname = _nickname!;
await _dbHelper.updateNickname(loginId, newNickname);
_nickname = newNickname;
// 친구들에게 알림 전송
await notifyFriendsAboutNicknameChange(loginId, oldNickname, newNickname);
notifyListeners();
}
Future<void> notifyFriendsAboutNicknameChange(
String loginId, String oldNickname, String newNickname) async {
List<String> friendIds = await _dbHelper.getFriendIds(loginId);
for (String friendId in friendIds) {
await NotificationService.sendNicknameChangeNotification(
oldNickname: oldNickname, newNickname: newNickname);
}
}
void updateFriendCount(int count) {
_friendCount = count;
notifyListeners();
}
}
3. nickname_change.dart
이 클래스는 사용자가 닉네임을 변경할 수 있는 UI를 제공합니다. 닉네임 변경 시 ProfileProvider의 updateNickname 메서드를 호출하여 친구들에게 알림을 보냅니다.
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:todomate/screens/my/profile_provider.dart';
import 'package:todomate/screens/my/profile_widget.dart';
class NicknameChange extends StatelessWidget {
final String loginId;
final String nickname;
final TextEditingController _nicknameController = TextEditingController();
NicknameChange({required this.loginId, required this.nickname});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Colors.grey,
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.black),
onPressed: () {
Navigator.pop(context);
},
),
),
resizeToAvoidBottomInset: false,
body: SafeArea(
child: Column(
children: [
ProfileWidget(nickname: nickname),
Expanded(
child: Container(
color: Colors.white,
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
children: [
SizedBox(height: 40.0),
TextField(
controller: _nicknameController,
decoration: InputDecoration(
hintText: 'New NickName',
hintStyle: TextStyle(
color: Colors.grey,
fontSize: 35.0,
fontWeight: FontWeight.normal,
),
filled: true,
fillColor: Colors.white,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide.none,
),
contentPadding: EdgeInsets.zero,
prefixIcon: Icon(
Icons.published_with_changes,
size: 40.0,
color: Colors.grey,
),
),
style: TextStyle(
color: Colors.black,
fontSize: 24.0,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
SizedBox(height: 50.0),
ElevatedButton(
onPressed: () {
context.read<ProfileProvider>().updateNickname(
loginId, _nicknameController.text);
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
elevation: 5,
shadowColor: Colors.grey.withOpacity(0.3),
padding: EdgeInsets.symmetric(
horizontal: 70.0, vertical: 10.0),
),
child: Text(
'Change',
style: TextStyle(
fontSize: 35.0,
color: Colors.grey,
),
),
),
SizedBox(height: 120.0),
ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.orange,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
padding: EdgeInsets.symmetric(
horizontal: 70.0, vertical: 10.0),
),
child: Text(
'Confirm',
style: TextStyle(
fontSize: 35.0,
color: Colors.white,
),
),
),
SizedBox(height: 60.0),
],
),
),
),
],
),
),
),
);
}
}
4. sharedpreference.dart
이 클래스는 SharedPreferences를 사용하여 알림 메시지를 저장하고 관리하는 역할을 수행합니다.
import 'package:shared_preferences/shared_preferences.dart';
class SharedPreferencesHelper {
static Future<void> storeNotification(String message) async {
final prefs = await SharedPreferences.getInstance();
List<String> notifications =
prefs.getStringList('notifications') ?? [];
notifications.add(message);
await prefs.setStringList('notifications', notifications);
}
static Future<List<String>> getStoredNotifications() async {
final prefs = await SharedPreferences.getInstance();
return prefs.getStringList('notifications') ?? [];
}
static Future<void> clearNotifications() async {
final prefs = await SharedPreferences.getInstance();
await prefs.remove('notifications');
}
}
5. user_provider.dart
코드 리뷰:
import 'package:flutter/foundation.dart';
import 'package:todomate/models/signup_model.dart';
class UserProvider with ChangeNotifier {
DatabaseHelper _dbHelper = DatabaseHelper();
Future<void> registerUser(Map<String, dynamic> user) async {
await _dbHelper.insertUser(user);
notifyListeners();
}
Future<Map<String, dynamic>?> loginUser(String loginId, String password) async {
return await _dbHelper.loginUser(loginId, password);
}
Future<void> sendFriendRequest(String userId, String friendId) async {
await _dbHelper.sendFriendRequest(userId, friendId);
notifyListeners();
}
Future<void> acceptFriendRequest(String userId, String friendId) async {
await _dbHelper.acceptFriendRequest(userId, friendId);
notifyListeners();
}
Future<List<Map<String, dynamic>>> searchUsers(String query, String userId) async {
return await _dbHelper.searchUsers(query, userId);
}
Future<List<Map<String, dynamic>>> getFriendRequests(String userId) async {
return await _dbHelper.getFriendRequests(userId);
}
}
'코딩 > ♠♠기술 구현' 카테고리의 다른 글
닉네임 변경후 알림보내기 작동 순서. (0) | 2024.08.23 |
---|---|
닉네임 변경후 알림 보내기(위에걸로 하기) (0) | 2024.08.23 |
프로바이더 이용한 닉네임 변경 다시 정리 (0) | 2024.08.23 |
상태관리 일기개수 추가 (1) | 2024.08.21 |
프로바이더로 ui 상태관리 (0) | 2024.08.20 |