Firebaseのメールアドレスを変更する
メールアドレス変わったら変更しないと...
スマホのメールアドレス変わっちゃった!
メールアドレスの変更が必要ですよね😅
Firebaseだと、簡単に変更できる便利な機能がありました!
こちらの記事を参考にさせていたただきました!
FlutterFireの公式によると
ユーザーのメールアドレスを設定する
ユーザーのメールアドレスを設定するには、updateEmail() メソッドを使用します。たとえば
await user?.updateEmail("janeq@example.com");
Formの値を引数で渡してあげればOKですね。
Demoアプリを作る
完成品のソースコード
まずは、Firebaseのプロジェクトを作りましよう。Google Analyticsはなしで良いです。
Flutterのプロジェクトを作成する
以下のpackageを追加して、認証機能に必要なファイルを作成してください。
name: email_update
description: A new Flutter project.
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.0.0+1
environment:
sdk: '>=2.18.0 <3.0.0'
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
firebase_core: ^2.4.1
firebase_auth: ^4.2.5
flutter_riverpod: ^2.1.3
dev_dependencies:
flutter_test:
sdk: flutter
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^2.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages
lib
├── main.dart
├── ui
│ ├── email_reset.dart
│ └── signin_page.dart
└── utils
├── auth_provider.dart
└── auth_state.dart
utilsディレクトリを作成して、FirebaseAuenticationを使用するためのProviderとロジックを作成しましよう。
FirebaseAuthenticationと、TextEditingControllerを使うためのProviderを作成。
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
final firebaseAuthProvider =
Provider<FirebaseAuth>((ref) => FirebaseAuth.instance);
final emailProvider = StateProvider.autoDispose((ref) {
return TextEditingController(text: '');
});
final passwordProvider = StateProvider.autoDispose((ref) {
return TextEditingController(text: '');
});
ユーザーの登録、ログイン、ログアウト、メールアドレスの変更ができるロジック
import 'package:email_update/ui/email_reset.dart';
import 'package:email_update/ui/signin_page.dart';
import 'package:email_update/utils/auth_provider.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
final authStateProvider = StateNotifierProvider<AuthState, dynamic>((ref) {
return AuthState(ref);
});
class AuthState extends StateNotifier<dynamic> {
final Ref _ref;
AuthState(this._ref) : super([]);
// ユーザーの新規登録.
Future<void> userSignUp(
String emailC, String passwordC, BuildContext context) async {
try {
final credential = await _ref
.read(firebaseAuthProvider)
.createUserWithEmailAndPassword(email: emailC, password: passwordC);
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => EmailRest()));
} on FirebaseAuthException catch (e) {
if (e.code == 'weak-password') {
print('提供されたパスワードが弱すぎる。');
} else if (e.code == 'email-already-in-use') {
print('その電子メールにはすでにアカウントが存在します。');
}
} catch (e) {
print(e);
}
}
// ユーザーのログイン.
Future<void> userSignIn(
String emailC, String passwordC, BuildContext context) async {
try {
final credential = await _ref
.read(firebaseAuthProvider)
.signInWithEmailAndPassword(email: emailC, password: passwordC);
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => EmailRest()));
} on FirebaseAuthException catch (e) {
if (e.code == 'user-not-found') {
print('そのメールに該当するユーザーは見つかりませんでした。');
} else if (e.code == 'wrong-password') {
print('そのユーザーに対して提供されたパスワードが間違っている。');
}
}
}
// ユーザーのログアウト.
Future<void> userSignOut(BuildContext context) async {
final credential = await _ref.read(firebaseAuthProvider).signOut();
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => SignInPage()));
}
// ユーザーのメールアドレスの変更.
Future<void> emailUpdate(String emailC) async {
final ref =
await _ref.read(firebaseAuthProvider).currentUser?.updateEmail(emailC);
}
}
メールアドレスを変更するページ
今回は、メールアドレスを変更する方法を学ぶのが目的なので、画面はこのページだけです🙇♂️
uiディレクトリを作成してその中にemail_reset.dartを作成。
import 'package:email_update/utils/auth_provider.dart';
import 'package:email_update/utils/auth_state.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class EmailRest extends ConsumerWidget {
const EmailRest({
Key? key,
}) : super(key: key);
Widget build(BuildContext context, WidgetRef ref) {
final emailC = ref.watch(emailProvider);
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
onPressed: () async {
ref.read(authStateProvider.notifier).userSignOut(context);
},
icon: Icon(Icons.logout))
],
title: const Text('SignIn'),
),
body: Center(
child: Container(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
// メールアドレス入力用テキストフィールド
TextFormField(
controller: emailC,
decoration: const InputDecoration(labelText: 'メールアドレス'),
),
ElevatedButton(
child: const Text('メールアドレスを変更する'),
onPressed: () async {
ref
.read(authStateProvider.notifier)
.emailUpdate(emailC.text);
}),
],
),
),
),
);
}
}
アプリを実行するコード
import 'package:email_update/ui/signin_page.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'firebase_options.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(
// Adding ProviderScope enables Riverpod for the entire project
const ProviderScope(child: MyApp()),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blueGrey,
),
home: const SignInPage(),
);
}
}
ユーザーを登録しておきます
メールアドレスを変更する場合は、ログインしてから、一定時間経過していると、エラーになるので、再ログインが必要です!
Firebase側から、送信されるメールのメッセージを英語から日本語に変更することができるので、設定しておきます。
メールアドレスは、変更してもメールのリンクから、最初に登録したメールアドレスに戻すことができます。
便利ですね。
まとめ
あまりメールアドレスの変更をする情報がないので、動くものを作ってみたいなと思ってDemoアプリを作ってみました。やってみた感想はそんなに難しくはないなと思いましたが、ログインから、時間が経っていると、再ログインが必要なところは注意が必要ですね!
Discussion