首页 > 解决方案 > 无法从包含 Firebase PhoneAutherisation 的未来提供商获取数据

问题描述

为了抽象代码,我使用了 FutureProvider 来完成 firebase 电话身份验证。我做错了什么,但如果有人可以帮助我用他/她的代码实现同样的目标,我将不胜感激。

这是主要代码:

Future<void> main() async {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        FutureProvider<VerificationProvider>(
          create: (context) => VerificationProvider().verifyPhone().catchError(
            (e) {
              print(e);
            },
          ),
        )
      ],
      child: MaterialApp(
        home: Delete(),
        routes: {
          Delete.id: (context) => Delete(),
        },
      ),
    );
  }
}

这是使用提供者提供身份验证的类:

class VerificationProvider with ChangeNotifier {
  FirebaseAuth _auth = FirebaseAuth.instance;
  String _verificationCode;
  String _phoneNo;
  FirebaseUser _user;

  void setPhoneNo(String phone) {
    _phoneNo = phone;
    notifyListeners();
  }

  void setVerificationCode(String code) {
    _verificationCode = code;
    notifyListeners();
  }

  FirebaseUser getUser() {
    return _user;
  }

  Future<void> verifyPhone() async {
    final PhoneCodeAutoRetrievalTimeout _autoRetrievalTimeout = (String verId) {
      print("auto verification executed");
    };

    final PhoneCodeSent _smsCodeSent = (String verId, [int forceCodeResend]) {
      AuthCredential _authCredentials = PhoneAuthProvider.getCredential(
          verificationId: verId, smsCode: _verificationCode);
      print("smsCodeSent Executed");
    };
    final PhoneVerificationCompleted _verificationCompleted =
        (AuthCredential _authCredentials) async {
      AuthResult result = await _auth.signInWithCredential(_authCredentials);
      _user = result.user;
      print("Logged in user is ${_user.phoneNumber}");
      print("phone verification completed");
    };
    final PhoneVerificationFailed _phoneVerificationFailed = (AuthException e) {
      print("phone verifiaction failed");
      print(e.message);
    };
    await _auth.verifyPhoneNumber(
      phoneNumber: _phoneNo,
      timeout: const Duration(seconds: 15),
      verificationCompleted: _verificationCompleted,
      verificationFailed: _phoneVerificationFailed,
      codeSent: _smsCodeSent,
      codeAutoRetrievalTimeout: _autoRetrievalTimeout,
    );
  }
}

在这个小部件中,我正在尝试使用它。

class Delete extends StatefulWidget {
  static String id = "Delete";
  @override
  _DeleteState createState() => _DeleteState();
}

class _DeleteState extends State<Delete> {
  String phoneNo;
  @override
  Widget build(BuildContext context) {
    var test = Provider.of<void>(context);  **//after adding this line i am getting error**
    return Scaffold(
      backgroundColor: Colors.orange,
      body: Center(
        child: Text("hu"),
      ),
    );
  }
}

错误:在此删除小部件上方找不到正确的提供程序

标签: flutterdartfirebase-authentication

解决方案


可以放 可以参考官方MultiProvider文档https://flutter.dev/docs/development/data-and-backend/state-mgmt/simple#changenotifierprovidermain()

代码片段

Future<void> main() async {
  runApp(
    MultiProvider(
      providers: [
        FutureProvider(
          create: (context) => VerificationProvider().verifyPhone().catchError(
            (e) {
              print(e);
            },
          ),
        )
      ],
      child: MyApp(),
    ),
  );
}

完整的测试代码

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:firebase_auth/firebase_auth.dart';

Future<void> main() async {
  runApp(
    MultiProvider(
      providers: [
        FutureProvider(
          create: (context) => VerificationProvider().verifyPhone().catchError(
            (e) {
              print(e);
            },
          ),
        )
      ],
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Delete(),
      routes: {
        Delete.id: (context) => Delete(),
      },
    );
  }
}

class VerificationProvider with ChangeNotifier {
  FirebaseAuth _auth = FirebaseAuth.instance;
  String _verificationCode;
  String _phoneNo;
  FirebaseUser _user;

  void setPhoneNo(String phone) {
    _phoneNo = phone;
    notifyListeners();
  }

  void setVerificationCode(String code) {
    _verificationCode = code;
    notifyListeners();
  }

  FirebaseUser getUser() {
    return _user;
  }

  Future<void> verifyPhone() async {
    final PhoneCodeAutoRetrievalTimeout _autoRetrievalTimeout = (String verId) {
      print("auto verification executed");
    };

    final PhoneCodeSent _smsCodeSent = (String verId, [int forceCodeResend]) {
      AuthCredential _authCredentials = PhoneAuthProvider.getCredential(
          verificationId: verId, smsCode: _verificationCode);
      print("smsCodeSent Executed");
    };
    final PhoneVerificationCompleted _verificationCompleted =
        (AuthCredential _authCredentials) async {
      AuthResult result = await _auth.signInWithCredential(_authCredentials);
      _user = result.user;
      print("Logged in user is ${_user.phoneNumber}");
      print("phone verification completed");
    };
    final PhoneVerificationFailed _phoneVerificationFailed = (AuthException e) {
      print("phone verifiaction failed");
      print(e.message);
    };
    await _auth.verifyPhoneNumber(
      phoneNumber: _phoneNo,
      timeout: const Duration(seconds: 15),
      verificationCompleted: _verificationCompleted,
      verificationFailed: _phoneVerificationFailed,
      codeSent: _smsCodeSent,
      codeAutoRetrievalTimeout: _autoRetrievalTimeout,
    );
  }
}

class Delete extends StatefulWidget {
  static String id = "Delete";
  @override
  _DeleteState createState() => _DeleteState();
}

class _DeleteState extends State<Delete> {
  String phoneNo;
  @override
  Widget build(BuildContext context) {
    var test = Provider.of<void>(context);
    return Scaffold(
      backgroundColor: Colors.orange,
      body: Center(
        child: Text("hu"),
      ),
    );
  }
}

推荐阅读