所以这是用于与验证器创建业务的代码,但是我遇到的问题是firebase验证器无法验证电话号码,因为现在它会产生一些我不熟悉的错误。
//import 'package:font_awesome/css/all.css';
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:kyereme/models/business.dart';
import 'package:kyereme/services/business_service.dart';
import 'package:flushbar/flushbar.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
import 'package:geolocator/geolocator.dart';
bool _submitting = false;
bool isLoading = false;
final FirebaseAuth _auth = FirebaseAuth.instance;
class ProfilePage extends StatefulWidget {
@override
_ProfilePageState createState() => _ProfilePageState();
}
SharedPreferences prefs;
String id = '';
//create image file
File _image;
//get image method
//upload image updated
class _ProfilePageState extends State<ProfilePage> {
@override
Widget build(BuildContext context) {
// context._formKey = _formKey;
return Scaffold(
appBar: AppBar(
title: Text('Add Account', style: TextStyle(color: Colors.white)),
centerTitle: true,
backgroundColor: Colors.lightBlueAccent,
iconTheme: IconThemeData(
color: Colors.white,
),
),
body: ModalProgressHUD(
child: Builder(builder: (BuildContext context) {
return _PhoneSignInSection(Scaffold.of(context));
}),
inAsyncCall: _submitting),
);
}
}
class _PhoneSignInSection extends StatefulWidget {
_PhoneSignInSection(this._scaffold);
final ScaffoldState _scaffold;
@override
State<StatefulWidget> createState() => _PhoneSignInSectionState();
}
class _PhoneSignInSectionState extends State<_PhoneSignInSection> {
final TextEditingController _phoneNumberController = TextEditingController();
final TextEditingController _smsController = TextEditingController();
final TextEditingController _businessNameController = TextEditingController();
final TextEditingController _productsController = TextEditingController();
static Position _currentLocation = Position();
static final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
String _message = '';
String _verificationId;
String photoURL;
String photoID;
String _businessTypeValue = 'Food';
List<String> _locations = [
'Food',
'Bar',
'Entertainment',
'Gas',
'Bathroom',
'Medical',
'Hospitality',
'Transportation'
];
@override
Widget build(BuildContext context) {
var profilePic = 'images/nav/user-pic-icon.png';
Future getImage() async {
var image = await ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
_image =image;
print('Image Path $_image');
});
}
void readLocal() async {
prefs = await SharedPreferences.getInstance();
id = prefs.getString('id') ?? '';
}
uploadPicture(BuildContext context) async{
/*
upload the picture
new
*/
final StorageReference profileImageRef = FirebaseStorage.instance.ref().child("profileImages");
var timekey = new DateTime.now();
final StorageUploadTask uploadTask = profileImageRef.child(timekey.toString()+ "jpg").putFile(_image);
var firebaseImageStorageURL = await(await uploadTask.onComplete).ref.getDownloadURL();
photoURL = firebaseImageStorageURL.toString();
// print("This is the image url" + photoURL);
}
final Size screenSize = MediaQuery.of(context).size;
return Stack(
fit: StackFit.expand,
children: <Widget>[
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Color(0x0cccee).withOpacity(1.0),
Color(0x00d8d4).withOpacity(0.8)
],
stops: [0.20, 3.0],
begin: FractionalOffset.bottomCenter,
),
),
),
Positioned.fill(
child: Image.asset(
'images/splash/background-icon.png',
fit: BoxFit.fitWidth,
alignment: Alignment.bottomLeft,
),
),
Center(
child: Container(
alignment: AlignmentDirectional(0.0, 0.0),
margin: EdgeInsets.only(
top: 30.0,
bottom: 30.0,
),
child: Container(
constraints: BoxConstraints(
maxHeight: screenSize.height - 20,
maxWidth: screenSize.width - 60,
),
child: Form(
key: _formKey,
child: ListView(
children: <Widget>[
SizedBox(height: 20.0),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Align(
alignment: Alignment.center,
child: CircleAvatar(
radius: 60,
backgroundColor: Color(0xffffff).withOpacity(1.0),
child: CircleAvatar(
radius: 55,
backgroundColor: Color(0xd8d8d8).withOpacity(1.0),
child: ClipOval(
child: SizedBox(
width: 180.0,
height: 180.0,
child:(_image!= null)?Image.file(_image,fit: BoxFit.fill)
:IconButton(
icon: Image.asset(
// this where the profile pic is located at
profilePic),
onPressed: (){
getImage();
},
),
),
),
),
),
),
Padding(
padding: EdgeInsets.only(top: 60.0),
child: IconButton(
icon: Icon(
Icons.camera_alt,
size: 30.0,
color: Colors.white,
),
onPressed: () {
getImage();
},
),
)
],
),
TextFormField(
controller: _businessNameController,
keyboardType: TextInputType.text,
decoration: InputDecoration(labelText: 'Business Name'),
validator: (String value) {
if (value.isEmpty) {
return 'Please enter your business name';
}
},
),
TextFormField(
controller: _phoneNumberController,
keyboardType: TextInputType.phone,
decoration: InputDecoration(labelText: 'Phone Number'),
validator: (String value) {
if (value.isEmpty) {
return 'Phone number (+x xxx-xxx-xxxx)';
}
},
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Container(
padding: EdgeInsets.only(top: 10),
child: new Text(
"Type of business: ",
style: TextStyle(
fontSize: 16, color: Colors.grey[800]),
),
),
new Container(
padding: EdgeInsets.only(top: 10),
child: DropdownButton<String>(
value: _businessTypeValue,
onChanged: (String newValue) {
setState(() {
_businessTypeValue = newValue;
});
},
items: <String>[
'Food',
'Bar',
'Entertainment',
'Bathroom',
'Medical',
'Hospitality',
'Transportation'
].map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
style: TextStyle(color: Colors.grey[800]),
),
);
}).toList(),
),
),
],
),
Container(
width: screenSize.width,
height: 50.0,
child: RaisedButton(
child: Row(
children: <Widget>[
Icon(Icons.navigation),
Text(
"Current Location",
style: TextStyle(color: Colors.white),
)
],
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
onPressed: () async {
_currentLocation = await Geolocator()
.getCurrentPosition(
desiredAccuracy:
LocationAccuracy.bestForNavigation);
},
color: Colors.transparent,
),
margin: EdgeInsets.only(
top: 30.0,
bottom: 30.0,
),
decoration: BoxDecoration(
color: Colors.transparent,
border: Border.all(color: Colors.white, width: 1.0),
borderRadius: BorderRadius.circular(10.0),
),
),
TextFormField(
controller: _productsController,
maxLines: 5,
keyboardType: TextInputType.multiline,
decoration: InputDecoration(
labelText:
'Product(s) Instructions on how to input here',
border: OutlineInputBorder()),
),
Container(
alignment: Alignment.center,
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Text(
_message,
style: TextStyle(color: Colors.red),
),
),
Container(
width: screenSize.width,
height: 50,
child: RaisedButton(
child: Text(
"Submit",
style: TextStyle(color: Colors.white),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
onPressed: () {
if (_formKey.currentState.validate()) {
_verifyPhoneNumber(context);
uploadPicture(context);
}
},
color: Colors.transparent,
),
margin: EdgeInsets.only(
top: 30.0,
bottom: 30.0,
),
decoration: BoxDecoration(
color: Colors.transparent,
border: Border.all(color: Colors.white, width: 1.0),
borderRadius: BorderRadius.circular(10.0),
),
),
],
),
),
),
),
)
],
);
}
_onCreate(String result) {
widget._scaffold.removeCurrentSnackBar();
widget._scaffold.showSnackBar(SnackBar(
content: Text(result),
));
setState(() {
_submitting = false;
});
}
_onCreateError(dynamic err) {
widget._scaffold.removeCurrentSnackBar();
widget._scaffold.showSnackBar(SnackBar(
content: Text(err),
));
setState(() {
_submitting = false;
});
}
这是用户选择提交的地方,它通过带有打字稿的后端解析提交,此处未显示,但调用了Firebase实例。
_submit(BuildContext context) async {
//uploadPicture(context);
setState(() {
_submitting = true;
});
var newBusiness = new Business();
newBusiness.businessName = _businessNameController.text;
newBusiness.businessType = _businessTypeValue;
newBusiness.phoneNumber = _phoneNumberController.text;
newBusiness.dob = new DateTime.now();
newBusiness.lat = _currentLocation.latitude;
newBusiness.long = _currentLocation.longitude;
newBusiness.products = _productsController.text.split(',');
newBusiness.photoUrl = photoURL;
print("Printing on Submit"+photoURL);
newBusiness.photoID = photoID;
// newBusiness
BusinessService()
.createBusiness(newBusiness)
.then((result) => _onCreate(result))
.catchError((err) => _onCreateError(err));
}
// widget._scaffold.showSnackBar(SnackBar(
// content:
// Text(_formKey.toString()),
// ));
// Exmaple code of how to veify phone number
这是处理电话号码验证,然后调用身份验证器以从Google进行其功能的部分。
void _verifyPhoneNumber(BuildContext context) async {
setState(() {
_message = '';
});
final PhoneVerificationCompleted verificationCompleted =
(AuthCredential user) {
setState(() {
_message = 'signInWithPhoneNumber auto succeeded: $user';
});
};
final PhoneVerificationFailed verificationFailed =
(AuthException authException) {
setState(() {
_message =
'Phone number verification failed. Code: ${authException.code}. Message: ${authException.message}';
});
};
final PhoneCodeSent codeSent =
(String verificationId, [int forceResendingToken]) async {
widget._scaffold.showSnackBar(SnackBar(
content:
const Text('Please check your phone for the verification code.'),
duration: new Duration(seconds: 2),
));
_verificationId = verificationId;
};
final PhoneCodeAutoRetrievalTimeout codeAutoRetrievalTimeout =
(String verificationId) {
_verificationId = verificationId;
};
await _auth
.verifyPhoneNumber(
phoneNumber: _phoneNumberController.text,
timeout: const Duration(seconds: 5),
verificationCompleted: verificationCompleted,
verificationFailed: verificationFailed,
codeSent: codeSent,
codeAutoRetrievalTimeout: codeAutoRetrievalTimeout)
.then((onValue) => {_showDialog(context)});
}
// Example code of how to sign in with phone.
_signInWithPhoneNumber(BuildContext context) async {
final AuthCredential credential = PhoneAuthProvider.getCredential(
verificationId: _verificationId,
smsCode: _smsController.text,
);
try {
final FirebaseUser user = await _auth.signInWithCredential(credential);
final FirebaseUser currentUser = await _auth.currentUser();
assert(user.uid == currentUser.uid);
setState(() {
if (user != null) {
_message = 'Successfully signed in, uid: ' + user.uid;
_submit(context);
} else {
_message = 'Sign in failed';
}
});
} catch (PlatformException) {
_message = 'Unable to verify your code';
}
return context;
}
_showDialog(BuildContext context) async {
// Toast.show("Toast plugin app", context,
// duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
Fluttertoast.showToast(
msg: "Toast plugin app",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM
);
await showDialog<String>(
barrierDismissible: false,
context: context,
builder: (BuildContext context) {
return SingleChildScrollView(
child: new _SystemPadding(
child: new AlertDialog(
contentPadding: const EdgeInsets.all(16.0),
title: new Text("Enter the code you just received."),
content: new Row(
children: <Widget>[
new Expanded(
child: new TextFormField(
controller: _smsController,
keyboardType: TextInputType.number,
decoration: InputDecoration(labelText: 'Verify Code'),
validator: (String value) {
if (value.isEmpty || value.toString().length < 6) {
return 'Enter 6 digits';
}
},
),
)
],
),
actions: <Widget>[
new RaisedButton(// cancell function of show dialog
child: Text("Cancel"),
onPressed: () async {
Navigator.pop(context);
},
color: Colors.red,
textColor: Colors.white,
splashColor: Colors.redAccent),
new RaisedButton(
child: Text("Verify"),
onPressed: () async {
Navigator.pop(context);
await _signInWithPhoneNumber(context);
},
color: Colors.blue,
textColor: Colors.white,
splashColor: Colors.blueAccent),
],
),
),
);
});
}
}
class _SystemPadding extends StatelessWidget {
final Widget child;
_SystemPadding({Key key, this.child}) : super(key: key);
@override
Widget build(BuildContext context) {
var mediaQuery = MediaQuery.of(context);
return new AnimatedContainer(
padding: mediaQuery.viewInsets,
duration: const Duration(milliseconds: 300),
child: child);
}
}
这是我输入测试电话号码并崩溃时指示的错误的堆栈跟踪
[VERBOSE-2:ui_dart_state.cc(157)] Unhandled Exception: NoSuchMethodError: The method 'existsSync' was called on null.
Receiver: null
Tried calling: existsSync()
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
#1 StorageReference.putFile (package:firebase_storage/src/storage_reference.dart:62:17)
#2 _PhoneSignInSectionState.build.uploadPicture (package:ky/pages/profile_page.dart:133:93)
#3 _AsyncAwaitCompleter.start (dart:async-patch/async_patch.dart:45:6)
#4 _PhoneSignInSectionState.build.uploadPicture (package:ky/pages/profile_page.dart:121:19)
#5 _PhoneSignInSectionState.build.<anonymous closure> (package:ky/pages/profile_page.dart:354:42)
#6 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:706:14)
#7 _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:789:36)
#8 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)
#9 TapGestu<…>
[C6.1 6AAE395C-5E7D-4AC4-99F0-53C557EAF96C 10.20.61.12:62085<->64.233.177.139:443]
Connected Path: satisfied (Path is satisfied), interface: en0
Duration: 124.650s, DNS @0.000s took 0.006s, TCP @0.007s took 0.018s, TLS took 0.037s
bytes in/out: 8761/4752, packets in/out: 33/29, rtt: 0.018s, retransmitted packets: 1, out-of-order packets: 0
Google Maps SDK for iOS cannot connect or validate APIKey: Error Domain=com.google.HTTPStatus Code=400 "(null)" UserInfo={data={length = 145, bytes = 0x3c48544d 4c3e0a3c 48454144 3e0a3c54 ... 3c2f4854 4d4c3e0a }}
Your key may be invalid for your bundle ID: