You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter后台发送邮件遇google_sign_in错误,求可行实现示例

问题1:The instance member 'scopes' can't be accessed in an initializer

Dart不允许在类成员变量的初始化器中引用另一个成员变量。解决方式二选一:

  • 把scopes直接内联到GoogleSignIn构造参数中
  • 用late关键字延迟初始化_googleSignIn,或在initState中完成初始化(仅适用于StatefulWidget)

问题2:googleSignIn.signIn()方法不存在

signIn()是实例方法,必须通过你创建的_googleSignIn实例调用,不能直接用GoogleSignIn类调用。


完整Flutter后台发送邮件实现示例

第一步:添加依赖

在pubspec.yaml中引入所需包:

dependencies:
  flutter:
    sdk: flutter
  google_sign_in: ^6.2.1
  mailer: ^6.1.1

第二步:完整代码实现

import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:mailer/mailer.dart';
import 'package:mailer/smtp_server/gmail.dart';

class EmailSender extends StatefulWidget {
  const EmailSender({super.key});

  @override
  State<EmailSender> createState() => _EmailSenderState();
}

class _EmailSenderState extends State<EmailSender> {
  // 直接内联权限范围,避免初始化器冲突
  final GoogleSignIn _googleSignIn = GoogleSignIn(
    scopes: <String>[
      'email',
      'https://www.googleapis.com/auth/gmail.send', // 发送邮件必须的权限,替换原contacts权限
    ],
    // 平台专属配置:Android/iOS/Web需填写在Google Cloud Console获取的clientId
    // clientId: 'your-client-id.apps.googleusercontent.com',
  );
  GoogleSignInAccount? _currentUser;

  @override
  void initState() {
    super.initState();
    // 监听登录状态变化
    _googleSignIn.onCurrentUserChanged.listen((account) {
      setState(() => _currentUser = account);
    });
    // 尝试静默登录(保留上次登录状态)
    _googleSignIn.signInSilently();
  }

  // Google登录操作
  Future<void> _handleSignIn() async {
    try {
      await _googleSignIn.signIn();
    } catch (error) {
      print('登录失败: $error');
    }
  }

  // 发送邮件核心逻辑
  Future<void> sendNewUserEmail() async {
    if (_currentUser == null) {
      print('请先完成Google账号登录');
      return;
    }

    // 获取OAuth2授权的accessToken
    final auth = await _currentUser!.authentication;
    final accessToken = auth.accessToken!;

    // 配置Gmail的SMTP服务器(OAuth2认证)
    final smtpServer = gmailSaslXoauth2(_currentUser!.email, accessToken);

    // 构建邮件内容
    final message = Message()
      ..from = Address(_currentUser!.email, 'Deal Diligence')
      ..recipients = ['newuser@gmail.com']
      ..subject = 'Welcome to Deal Diligence'
      ..text = 'Welcome to Deal Diligence. Your password is NewPassword';

    try {
      final report = await send(message, smtpServer);
      print('邮件发送成功: ${report.toString()}');
    } on MailerException catch (e) {
      print('邮件发送失败: ${e.toString()}');
      for (var problem in e.problems) {
        print('错误详情: ${problem.code} - ${problem.msg}');
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('邮件发送测试')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            _currentUser != null
                ? Text('当前登录账号: ${_currentUser!.email}')
                : const Text('未登录'),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: _currentUser == null ? _handleSignIn : null,
              child: const Text('登录Google账号'),
            ),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: _currentUser != null ? sendNewUserEmail : null,
              child: const Text('发送欢迎邮件'),
            ),
          ],
        ),
      ),
    );
  }
}

void main() => runApp(const MaterialApp(home: EmailSender()));

关键注意事项

  • 权限配置:必须使用https://www.googleapis.com/auth/gmail.send权限,才能通过Gmail API发送邮件
  • 平台配置:需在Google Cloud Console创建项目、启用Gmail API、配置OAuth同意屏幕,并获取对应平台的clientId,完成Android/iOS/Web的登录配置
  • 账号限制:普通Gmail账号需确保已在Google Cloud Console完成OAuth认证配置,否则会出现权限拦截问题

内容的提问来源于stack exchange,提问作者LostTexan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 05:55:33