まえがき
2020年からFlutterの勉強を初めました。
Firebase連携でアプリを作っているのですが、その時ユーザー作成したタイミングとかで認証メールってどうやって送るんだろと思いました。
結果それはFirebase Authenticationの機能であるので、コード一文だけでできるのですが、
調べる中で、メール関係のパッケージってたくさんあるんだなと知りました。
メールを送信するんだろうなと思われるパッケージでもいくつかあって、何が違うのかよくわからないんですよね。
なのでよく見るこの二つを使ってみました。
- url_launcher
- flutter_email_sender
とはいえ、深いところはあまりわからず、表面的な使い方を紹介すると言う記事になっているので、そこらへんはご了承を。
Firebaseから認証メールの送り方も最後に簡単に説明しますね、
url_launcher
このパッケージは僕は前にも記事を書いたのですが。→url_launcherの使い方
URLをアプリ内で起動させるパッケージです。
その中の機能はURLを起動させるだけでなく、メール送信や電話やSMSなどがあります。
今回はそのメール送信についてですね
flutter_email_sender
このパッケージは単純にメールを送るためのパッケージですね
こっちの方が他の機能がない分シンプルでいいかも
サンプル
フォームにメールアドレスを入力してそこのメールアドレスにメールを送るというサンプルを作成しました。
送り元のメールアドレスは、デバイスのメールアドレスが使用されるので実機でテストしてみてください。
(ちなみに僕はiOSです。)
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:flutter_email_sender/flutter_email_sender.dart';
class MailPackage extends StatefulWidget {
@override
State<StatefulWidget> createState() => _MailPackage();
}
class _MailPackage extends State<MailPackage> {
TextEditingController emailController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('メールパッケージ'),
),
body: Container(
padding: EdgeInsets.all(30),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextFormField(
controller: emailController,
decoration: InputDecoration(hintText: 'メールアドレスを入力してください'),
),
RaisedButton(
child: Text('url_launcherで送る'),
onPressed: () {
urlLauncherMail();
},
),
RaisedButton(
child: Text('flutter_email_senderで送る'),
onPressed: () {
flutterEmailSenderMail();
},
)
],
),
),
);
}
//url_launcherを使ってメールを送信
urlLauncherMail() {
final Uri _emailLaunchUri = Uri(
scheme: 'mailto',
path: '${emailController.text}',
queryParameters: {
'subject': 'url_launcherを使ってメールを送ります!',
'body': '${Template().text}'
},
);
return launch(
_emailLaunchUri.toString(),
);
}
//flutter_email_senderを使ってメールを送信
flutterEmailSenderMail() async {
final Email email = Email(
body: '${Template().text}',
subject: 'flutter_email_senderを使ってメールを送っています!',
recipients: ['${emailController.text}'],
attachmentPaths: ['images/sample1.png'],
);
await FlutterEmailSender.send(email);
}
}
//本文のテンプレート的な
class Template {
String text =
'お疲れ様です。テスト通知です。\n\nメールは届いているでしょうか?\n\n届いておりましたら、お返事お待ちしております。\nこちらのURLもみてくださいね\n\nhttps://qiita.com/ryota47/items/fb8e32f1a409026ba065';
}
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:flutter_email_sender/flutter_email_sender.dart';
class MailPackage extends StatefulWidget {
@override
State<StatefulWidget> createState() => _MailPackage();
}
class _MailPackage extends State<MailPackage> {
TextEditingController emailController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('メールパッケージ'),
),
body: Container(
padding: EdgeInsets.all(30),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextFormField(
controller: emailController,
decoration: InputDecoration(hintText: 'メールアドレスを入力してください'),
),
RaisedButton(
child: Text('url_launcherで送る'),
onPressed: () {
urlLauncherMail();
},
),
RaisedButton(
child: Text('flutter_email_senderで送る'),
onPressed: () {
flutterEmailSenderMail();
},
)
],
),
),
);
}
//url_launcherを使ってメールを送信
urlLauncherMail() {
final Uri _emailLaunchUri = Uri(
scheme: 'mailto',
path: '${emailController.text}',
queryParameters: {
'subject': 'url_launcherを使ってメールを送ります!',
'body': '${Template().text}'
},
);
return launch(
_emailLaunchUri.toString(),
);
}
//flutter_email_senderを使ってメールを送信
flutterEmailSenderMail() async {
final Email email = Email(
body: '${Template().text}',
subject: 'flutter_email_senderを使ってメールを送っています!',
recipients: ['${emailController.text}'],
attachmentPaths: ['images/sample1.png'],
);
await FlutterEmailSender.send(email);
}
}
//本文のテンプレート的な
class Template {
String text =
'お疲れ様です。テスト通知です。\n\nメールは届いているでしょうか?\n\n届いておりましたら、お返事お待ちしております。\nこちらのURLもみてくださいね\n\nhttps://qiita.com/ryota47/items/fb8e32f1a409026ba065';
}
説明
全体は、フォームとボタン二つを配置して、各パッケージのメール送信ができるように関数を作りボタンの中に置きました。
メールの本文用のテンプレートとなるTemplate
クラスも作ってみました。
url_launcherの使い方
url_launcherパッケージを使ってメールを送信するのはこちらのコードです。
urlLauncherMail() {
final Uri _emailLaunchUri = Uri(
scheme: 'mailto',
path: '${emailController.text}',
queryParameters: {
'subject': 'url_launcherを使ってメールを送ります!',
'body': '${Template().text}'
},
);
return launch(
_emailLaunchUri.toString(),
);
}
Uri
クラスを定義して、
- scheme
:mailto
- path
:送る先のメールアドレス
- queryParameters
:内容。subject
が件名、body
が本文
それを、launch
の引数で渡すことで、メール送信画面に遷移します。toString()
することを忘れずに。
flutter_email_senderの使い方
flutter_email_senderを使ってメールを送信するのはこちらのコードです。
flutterEmailSenderMail() async {
final Email email = Email(
body: '${Template().text}',
subject: 'flutter_email_senderを使ってメールを送っています!',
recipients: ['${emailController.text}'],
);
await FlutterEmailSender.send(email);
}
Email
で
- body
:本文
- subject
:件名
- recipients
:送る先のメールアドレス
他にもcc
,bcc
,isHTML
,attachmentPaths
を渡せます。
attachmentPaths
はなんなのかはまだちょっと理解できてないです。。
これをFlutterEmailSender.send(email)
のように引数で渡せばメール送信画面に遷移します。
またrecipients
,cc
,bcc
はList<String>
で定義されているため、複数のメールアドレスを渡すことができそうです。
違いと、どっちがいいか
二つともコードはなんとなく似ていますが、この二つのパッケージは大きな違いがあります。
それぞれメール送信画面に遷移するんですが、
url_launcherはメールのアプリに遷移します。(おそらくユニバーサルリンクを踏んでいる)したがって、メールを送信した後はメールのアプリを開いている状態になります。
しかしflutter_email_senderはそのアプリ内でメール送信画面が起動します。したがってメールを送信してもそのアプリが開かれた状態になります。
これならflutter_email_senderの方を使っちゃいそうだな〜
flutter_email_senderの方が本文、件名を設定するのも若干簡単だし。
cc,bccが簡単に作れるので便利そう。
ソースコードを読んでみた感想
flutter_email_senderのEmail
クラスを開いたら、すごくシンプルで、「あれもしかしてメール送信ってパッケージ使わなくても簡単なのか?」と思いました。
しかしreturn
で返してるMethodChannel
を開くとなんか複雑で、ヒョエ〜ってなってやめました。
Firebaseからメール送る方法
最後におまけでFirebase Authenticationからメールを送る方法を紹介します。
Firebase Authenticationをブラウザで開き、Templatesを開きます。
そこに、メール認証のテンプレートがあります。
- メールアドレスの確認
FirebaseUser currentUser = await FirebaseAuth.instance.currentUser();
await currentUser.sendEmailVerification();
- パスワードの再設定
FirebaseAuth auth = FirebaseAuth.instance;
await auth.sendPasswordResetEmail(email: null);
- メールアドレスの変更
FirebaseAuth auth = FirebaseAuth.instance;
await auth.sendSignInWithEmailLink(
email: null,
url: null,
handleCodeInApp: null,
iOSBundleID: null,
androidPackageName: null,
androidInstallIfNotAvailable: null,
androidMinimumVersion: null);
これで送れそうです。
null
のところにはそれぞれ値を入れる必要があります。
メールアドレスの変更には、リセット用のリンクがありその時は匿名のサインインが必要になるらしく
匿名のサインイン機能をオンにしておく必要がありそうです。
(まだちゃんと試してないので、違かったらすいません。)