Flutter Firebase电话身份验证-如何获取身份验证令牌

时间:2018-09-30 14:30:08

标签: firebase firebase-authentication flutter

在我的应用程序中,我同时具有电子邮件和电话身份验证,当我使用电子邮件登录时,它会给我一个长的身份验证令牌,我可以使用它来读写数据库,但是,当我使用电话登录时,我只会得到一个短令牌,似乎不满足auth令牌的位置,因为它既不读取也不写入数据库。知道我如何能够获得电话身份验证的正确身份验证令牌吗?

  String phoneNo;
  String smsCode;
  String verificationId;
  String uid;

  Future<void> verifyPhone() async {
  final PhoneCodeAutoRetrievalTimeout autoRetrieve = (String verId) {
  this.verificationId = verId;
};

final PhoneCodeSent smsCodeSent = (String verId, [int forceCodeResend]) {
  this.verificationId = verId;
  smsCodeDialog(context).then((value) {
    print('Signed in');
  });
};

final PhoneVerificationCompleted verifiedSuccess = (FirebaseUser user) {
  print('verified');
};

final PhoneVerificationFailed veriFailed = (AuthException exception) {
  print('${exception.message}');
};

await FirebaseAuth.instance.verifyPhoneNumber(
    phoneNumber: this.phoneNo,
    codeAutoRetrievalTimeout: autoRetrieve,
    codeSent: smsCodeSent,
    timeout: const Duration(seconds: 5),
    verificationCompleted: verifiedSuccess,
    verificationFailed: veriFailed);
}

 Future<bool> smsCodeDialog(BuildContext context) {
return showDialog(
    context: context,
    barrierDismissible: false,
    builder: (BuildContext context) {
      return new AlertDialog(
        title: Text('Enter sms Code'),
        content: TextField(
          onChanged: (value) {
            this.smsCode = value;
          },
        ),
        contentPadding: EdgeInsets.all(10.0),
        actions: <Widget>[
          new FlatButton(
            child: Text('Done'),
            onPressed: () {
              FirebaseAuth.instance.currentUser().then((user) {
                if (user != null) {
                  setState(() {
                    this.uid = user.uid;
                  });
                  _submitForm(widget.model.authenticatePhone, 2);
                  Navigator.of(context).pop();
                  Navigator.of(context).pushReplacementNamed('/');
                } else {
                  Navigator.of(context).pop();
                  signIn();
                }
              });
            },
          )
        ],
      );
    });
}

signIn() {
FirebaseAuth.instance
    .signInWithPhoneNumber(verificationId: verificationId, smsCode: smsCode)
    .then((user) {
  Navigator.of(context).pushReplacementNamed('/');
}).catchError((e) {
  print(e);
});
}

电子邮件代码:

 Future<Map<String, dynamic>> authenticate(
  String email, String password, String token,
  [AuthMode mode = AuthMode.Login]) async {
_isLoading = true;
notifyListeners();
final Map<String, dynamic> authData = {
  'email': email,
  'password': password,
  'returnSecureToken': true,
};
http.Response response;
if (mode == AuthMode.Login) {
  response = await http.post(
    'https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key=[API]',
    body: json.encode(authData),
    headers: {'Content-Type': 'application/json'},
  );
} else {
  response = await http.post(
      'https://www.googleapis.com/identitytoolkit/v3/relyingparty/signupNewUser?key=[API]',
      body: json.encode(authData),
      headers: {'Content-Type': 'application/json'});
}

final Map<String, dynamic> responseData = json.decode(response.body);
bool hasError = true;
String message = 'Something went wrong!';
print(responseData);
if (responseData.containsKey('idToken')) {
  hasError = false;
  message = 'Authentication succeeded!';
  print(responseData['localId']);
  _authenticatedUser = User(
      id: responseData['localId'],
      email: email,
      token: responseData['idToken']);
  setAuthTimeout(int.parse(responseData['expiresIn']));
  _userSubject.add(true);

  addToken(token, _authenticatedUser.email);

  final DateTime now = DateTime.now();
  final DateTime expiryTime =
      now.add(Duration(seconds: int.parse(responseData['expiresIn'])));
  final SharedPreferences prefs = await SharedPreferences.getInstance();
  prefs.setString('token', responseData['idToken']);
  prefs.setString('userEmail', email);
  prefs.setString('userId', responseData['localId']);
  prefs.setString('expiryTime', expiryTime.toIso8601String());
} else if (responseData['error']['message'] == 'EMAIL_NOT_FOUND') {
  message = 'This email was not found!';
} else if (responseData['error']['message'] == 'EMAIL_EXISTS') {
  message = 'This email already exists!';
} else if (responseData['error']['message'] == 'INVALID_PASSWORD') {
  message = 'This password is invalid!';
}
_isLoading = false;
notifyListeners();

return {
  'success': !hasError,
  'message': message,
};
}

写入数据库:

http.Response responseToken;
  responseToken = await http.put(
      'https://app.firebaseio.com/tokens/${_authenticatedUser.id}/token.json?auth=${_authenticatedUser.token}',
      body: json.encode(token));

从数据库中读取

return http
    .get(
        'https://app.firebaseio.com/products.json?auth=${_authenticatedUser.token}')

1 个答案:

答案 0 :(得分:1)

使用firebase auth使用电子邮件和密码登录不必太复杂。只需这样做:

  FirebaseUser user = await FirebaseAuth.instance.signInWithEmailAndPassword(
    email: email,
    password: password
  );

  uid = user.uid;

而且,应该以firebase方式而不是旧的http方式来完成对数据库的读写操作。

写作:

FirebaseDatabase.instance.reference("users/$uid").set("test");

阅读:

final data = await FirebaseDatabase.instance.reference("users/$uid").once();