I am writing a FLUTTER application and I am trying to upload an image on the Firebase storage. This is a simple test app I've created to reproduce the error.
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:path_provider/path_provider.dart';
import 'package:firebase_storage/firebase_storage.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
File image;
Future<File> getImageFileFromAssets(String path) async {
final byteData = await rootBundle.load('assets/$path');
final file = File('${(await getTemporaryDirectory()).path}/$path');
await file.writeAsBytes(byteData.buffer
.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
return file;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Test App'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
height: 300,
width: 450,
child: image == null ? null : Image.file(image),
),
RaisedButton(
child: Text('Submit'),
onPressed: () async {
final fileName = 'imageName';
final firebaseStorageRef =
FirebaseStorage.instance.ref().child('userFolder');
final uploadTask =
firebaseStorageRef.child(fileName).putFile(image);
await uploadTask.onComplete;
},
),
RaisedButton(
child: Text('Load immagine'),
onPressed: () async {
image = await getImageFileFromAssets('test.jpg');
setState(() {});
},
),
],
),
),
);
}
}
As you can see when I click on the Load Image button I take an image from the assets and I store it in a File object, and it works fine. Then when I want to upload that image on Firebase's storage using the Submit button I get this error:
E/MethodChannel#plugins.flutter.io/firebase_storage(19436): Failed to handle method call
E/MethodChannel#plugins.flutter.io/firebase_storage(19436): java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process com.example.test_project. Make sure to call FirebaseApp.initializeApp(Context) first.
E/MethodChannel#plugins.flutter.io/firebase_storage(19436): at com.google.firebase.FirebaseApp.getInstance(com.google.firebase:firebase-common##17.0.0:234)
E/MethodChannel#plugins.flutter.io/firebase_storage(19436): at com.google.firebase.storage.FirebaseStorage.getInstance(com.google.firebase:firebase-storage##17.0.0:86)
E/MethodChannel#plugins.flutter.io/firebase_storage(19436): at io.flutter.plugins.firebase.storage.FirebaseStoragePlugin.onMethodCall(FirebaseStoragePlugin.java:57)
E/MethodChannel#plugins.flutter.io/firebase_storage(19436): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:222)
E/MethodChannel#plugins.flutter.io/firebase_storage(19436): at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:96)
E/MethodChannel#plugins.flutter.io/firebase_storage(19436): at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:656)
E/MethodChannel#plugins.flutter.io/firebase_storage(19436): at android.os.MessageQueue.nativePollOnce(Native Method)
E/MethodChannel#plugins.flutter.io/firebase_storage(19436): at android.os.MessageQueue.next(MessageQueue.java:326)
E/MethodChannel#plugins.flutter.io/firebase_storage(19436): at android.os.Looper.loop(Looper.java:160)
E/MethodChannel#plugins.flutter.io/firebase_storage(19436): at android.app.ActivityThread.main(ActivityThread.java:6669)
E/MethodChannel#plugins.flutter.io/firebase_storage(19436): at java.lang.reflect.Method.invoke(Native Method)
E/MethodChannel#plugins.flutter.io/firebase_storage(19436): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
E/MethodChannel#plugins.flutter.io/firebase_storage(19436): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
E/flutter (19436): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: PlatformException(error, Default FirebaseApp is not initialized in this process com.example.test_project. Make sure to call FirebaseApp.initializeApp(Context) first., null)
E/flutter (19436): #0 StandardMethodCodec.decodeEnvelope
package:flutter/…/services/message_codecs.dart:569
E/flutter (19436): #1 MethodChannel.invokeMethod
package:flutter/…/services/platform_channel.dart:316
E/flutter (19436): <asynchronous suspension>
E/flutter (19436): #2 _StorageFileUploadTask._platformStart
package:firebase_storage/src/upload_task.dart:130
E/flutter (19436): #3 StorageUploadTask._start
package:firebase_storage/src/upload_task.dart:35
E/flutter (19436): <asynchronous suspension>
E/flutter (19436): #4 StorageReference.putFile
package:firebase_storage/src/storage_reference.dart:65
E/flutter (19436): #5 _MyHomePageState.build.<anonymous closure>
package:test_project/main.dart:60
E/flutter (19436): <asynchronous suspension>
E/flutter (19436): #6 _InkResponseState._handleTap
package:flutter/…/material/ink_well.dart:654
E/flutter (19436): #7 _InkResponseState.build.<anonymous closure>
package:flutter/…/material/ink_well.dart:729
E/flutter (19436): #8 GestureRecognizer.invokeCallback
package:flutter/…/gestures/recognizer.dart:182
E/flutter (19436): #9 TapGestureRecognizer._checkUp
package:flutter/…/gestures/tap.dart:365
E/flutter (19436): #10 TapGestureRecognizer.handlePrimaryPointer
package:flutter/…/gestures/tap.dart:275
E/flutter (19436): #11 PrimaryPointerGestureRecognizer.handleEvent
package:flutter/…/gestures/recognizer.dart:455
E/flutter (19436): #12 PointerRouter._dispatch
package:flutter/…/gestures/pointer_router.dart:75
E/flutter (19436): #13 PointerRouter.route
package:flutter/…/gestures/pointer_router.dart:102
E/flutter (19436): #14 GestureBinding.handleEvent
package:flutter/…/gestures/binding.dart:218
E/flutter (19436): #15 GestureBinding.dispatchEvent
package:flutter/…/gestures/binding.dart:198
E/flutter (19436): #16 GestureBinding._handlePointerEvent
package:flutter/…/gestures/binding.dart:156
E/flutter (19436): #17 GestureBinding._flushPointerEventQueue
package:flutter/…/gestures/binding.dart:102
E/flutter (19436): #18 GestureBinding._handlePointerDataPacket
package:flutter/…/gestures/binding.dart:86
E/flutter (19436): #19 _rootRunUnary (dart:async/zone.dart:1136:13)
E/flutter (19436): #20 _CustomZone.runUnary (dart:async/zone.dart:1029:19)
E/flutter (19436): #21 _CustomZone.runUnaryGuarded (dart:async/zone.dart:931:7)
E/flutter (19436): #22 _invoke1 (dart:ui/hooks.dart:263:10)
E/flutter (19436): #23 _dispatchPointerDataPacket (dart:ui/hooks.dart:172:5)
E/flutter (19436):
Database's rules are the public ones:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write;
}
}
}
Can someone tell me what am I doing wrong?
According to docs just change your main method:
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
For who come here, I solved the problem. There is a lot of stuff to do, such as add your app to your Firebase project and edit some files.
The only thing to do is to read better the docs and follow all the steps:
Add Firebase to your Flutter app
All Firebase versions have been updated and now you have to call Firebase.initializeApp() before using any Firebase product, for example:
First, all Firebase products now depend on firebase_core version (0.5.0+), therefore you need to add it in the pubspec.yaml file:
dependencies:
flutter:
sdk: flutter
firebase_core : ^0.5.0
Then you have to call Firebase.initializeApp():
In the main.dart:
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(); //Make sure you imported firebase_core
runApp(MaterialApp(
home: GettingStartedPage(),
));
}
import 'package:firebase_core/firebase_core.dart';
Add the apply plugin to the [project]/android/app/build.gradle file.
apply plugin: 'com.google.gms.google-services'
Add this at root gradle in android/build.gradle
classpath 'com.google.gms:google-services:4.3.5'
check https://github.com/flutter/plugins/blob/master/packages/firebase_auth/README.md
Related
We have education app created with Flutter, this app very same to Udemy app features.
in this app the course may contain videos lectures of PDF files
all things working well except PDF downloading
The situation is:
when user click on PDF file name in lectures list, will open download page, it's contain only one button
when user click download button, download process start and download notification appear in notifications area
after few seconds notification show file link and failed message
I'm not sure what the problem here
Note that: the app was published on play & app store, and the PDF file download is fail in test mode and published versions.
the run log file for download process:
E/flutter (27102): #5 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
E/flutter (27102): #6 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
E/flutter (27102): #7 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
E/flutter (27102): #8 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:733:19)
E/flutter (27102): #9 _StreamController._add (dart:async/stream_controller.dart:607:7)
E/flutter (27102): #10 _StreamController.add (dart:async/stream_controller.dart:554:5)
E/flutter (27102): #11 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:192:12)
E/flutter (27102):
D/DownloadWorker(27102): Content-Type = application/pdf
D/DownloadWorker(27102): Content-Length = 1165606
D/DownloadWorker(27102): Charset = null
D/DownloadWorker(27102): Content-Disposition = null
D/DownloadWorker(27102): fileName = 7339d9826c027c3facdf76b943e452eb.pdf
W/System.err(27102): java.io.IOException: Permission denied
W/System.err(27102): at java.io.UnixFileSystem.createFileExclusively0(Native Method)
W/System.err(27102): at java.io.UnixFileSystem.createFileExclusively(UnixFileSystem.java:317)
W/System.err(27102): at java.io.File.createNewFile(File.java:1008)
W/System.err(27102): at vn.hunghd.flutterdownloader.DownloadWorker.createDownloadFileWithDirectFilePath(DownloadWorker.java:490)
W/System.err(27102): at vn.hunghd.flutterdownloader.DownloadWorker.downloadFile(DownloadWorker.java:393)
W/System.err(27102): at vn.hunghd.flutterdownloader.DownloadWorker.doWork(DownloadWorker.java:232)
W/System.err(27102): at androidx.work.Worker$1.run(Worker.java:86)
W/System.err(27102): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
W/System.err(27102): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
W/System.err(27102): at java.lang.Thread.run(Thread.java:919)
E/DownloadWorker(27102): Create a file using java.io API failed
D/DownloadWorker(27102): Update too frequently!!!!, but it is the final update, we should sleep a second to ensure the update call can be processed
E/flutter (27102): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: setState() called after dispose(): _MyCourseDownloadScreenState#6a6b6(lifecycle state: defunct, not mounted)
E/flutter (27102): This error happens if you call setState() on a State object for a widget that no longer appears in the widget tree (e.g., whose parent widget no longer includes the widget in its build). This error can occur when code calls setState() from a timer or an animation callback.
E/flutter (27102): The preferred solution is to cancel the timer or stop listening to the animation in the dispose() callback. Another solution is to check the "mounted" property of this object before calling setState() to ensure the object is still in the tree.
E/flutter (27102): This error might indicate a memory leak if setState() is being called because another object is retaining a reference to this State object after it has been removed from the tree. To avoid memory leaks, consider breaking the reference to this object during dispose().
E/flutter (27102): #0 State.setState.<anonymous closure> (package:flutter/src/widgets/framework.dart:1052:9)
E/flutter (27102): #1 State.setState (package:flutter/src/widgets/framework.dart:1087:6)
E/flutter (27102): #2 _MyCourseDownloadScreenState.initState.<anonymous closure> (package:connect/screens/my_course_download_screen.dart:43:7)
E/flutter (27102): #3 _rootRunUnary (dart:async/zone.dart:1444:13)
E/flutter (27102): #4 _CustomZone.runUnary (dart:async/zone.dart:1335:19)
E/flutter (27102): #5 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
E/flutter (27102): #6 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
E/flutter (27102): #7 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
E/flutter (27102): #8 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:733:19)
E/flutter (27102): #9 _StreamController._add (dart:async/stream_controller.dart:607:7)
E/flutter (27102): #10 _StreamController.add (dart:async/stream_controller.dart:554:5)
E/flutter (27102): #11 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:192:12)
E/flutter (27102):
D/Surface (27102): Surface::disconnect(this=0x701217d000,api=1)
D/View (27102): [Warning] assignParent to null: this = android.widget.FrameLayout{f9df83 V.E...... ......ID 0,0-376,125}
I/InputTransport(27102): Destroy ARC handle: 0x708af9a7c0
D/DownloadWorker(27102): Update notification: {notificationId: 3, title: https://connect-elearning.com/newVersion/uploads/lesson_files/7339d9826c027c3facdf76b943e452eb.pdf, status: 4, progress: -1}
W/System.err(27102): java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.io.File.getPath()' on a null object reference
W/System.err(27102): at vn.hunghd.flutterdownloader.DownloadWorker.downloadFile(DownloadWorker.java:394)
W/System.err(27102): at vn.hunghd.flutterdownloader.DownloadWorker.doWork(DownloadWorker.java:232)
W/System.err(27102): at androidx.work.Worker$1.run(Worker.java:86)
W/System.err(27102): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
W/System.err(27102): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
W/System.err(27102): at java.lang.Thread.run(Thread.java:919)
I/WM-WorkerWrapper(27102): Worker result FAILURE for Work [ id=99a29ba5-9003-4ef4-9f19-9fda892a3c5b, tags={ flutter_download_task, vn.hunghd.flutterdownloader.DownloadWorker } ]
download page code:
import 'dart:io';
import 'dart:isolate';
import 'dart:ui';
import 'package:connect/models/common_functions.dart';
import 'package:connect/widgets/app_bar_two.dart';
import 'package:file_utils/file_utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import '../constants.dart';
class MyCourseDownloadScreen extends StatefulWidget {
static const routeName = '/my-download-screen';
#override
_MyCourseDownloadScreenState createState() => _MyCourseDownloadScreenState();
}
class _MyCourseDownloadScreenState extends State<MyCourseDownloadScreen> {
int progress = 0;
ReceivePort _receivePort = ReceivePort();
static downloadingCallback(id, status, progress) {
///Looking up for a send port
SendPort sendPort = IsolateNameServer.lookupPortByName("downloading");
///ssending the data
sendPort.send([id, status, progress]);
}
#override
void initState() {
super.initState();
IsolateNameServer.registerPortWithName(_receivePort.sendPort, "downloading");
///Listening for the data is coming other isolates
_receivePort.listen((message) {
progress = message[2];
setState(() {
progress = message[2];
});
print(progress);
});
FlutterDownloader.registerCallback(downloadingCallback);
}
#override
Widget build(BuildContext context) {
final selectedUrl = ModalRoute.of(context).settings.arguments as String;
return Scaffold(
appBar: CustomAppBarTwo(),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FlatButton(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text("Download File", style: TextStyle(fontSize: 18),),
),
color: Colors.redAccent,
textColor: Colors.white,
onPressed: () async {
final status = await Permission.storage.request();
String externalDir = "";
if (status.isGranted) {
if (Platform.isAndroid) {
externalDir = "/sdcard/download/";
} else {
externalDir = (await getApplicationDocumentsDirectory()).path;
}
try {
FileUtils.mkdir([externalDir]);
final id = await FlutterDownloader.enqueue(
url: selectedUrl,
savedDir: externalDir,
// fileName: "download1234.pdf",
showNotification: true,
openFileFromNotification: true,
);
CommonFunctions.showSuccessToast("Downloading");
} catch(e){
print(e.getMessage());
CommonFunctions.showSuccessToast("Download Error");
}
} else {
print("Permission denied");
}
},
)
],
),
),
);
}
}
What I trying to do here is getting data from the 000webhost.com and passing that to my model class. That model class is being passed to the provider. Now when I try to display the information in my screen i am getting error.
In this case i have a model class called StudentData.
class StudentData {
final String rollNumber;
final String firstName;
final String lastName;
StudentData({
this.rollNumber,
this.firstName,
this.lastName,
});
}
Here I am fetching data using http package from internet.
And passing the decoded data to the StudentData class and passing that to my data_provider
import 'package:http/http.dart' as http;
void getStudentData(String currentEmail, BuildContext context) async {
final _url = 'https://aaa.000webhostapp.com/getStudentData.php';
final response = await http.post(_url, body: {'email': currentEmail});
var data = response.body;
final decodedData = jsonDecode(data);
final myRollNumber = decodedData['roll_number'];
final myFirstName = decodedData['first_name'];
final myLastName = decodedData['last_name'];
final myStudentData = StudentData(
rollNumber: myRollNumber, firstName: myFirstName, lastName: myLastName);
Provider.of<DataProvider>(context, listen: false)
.getMyStudentData(myStudentData);
}
Here is my DataProvider
class DataProvider extends ChangeNotifier {
StudentData myStudentData;
void getMyStudentData(StudentData studentData) {
myStudentData = studentData;
notifyListeners();
}
}
After that I have tried to fetch those information in my Screen
class StudentDashboard extends StatelessWidget {
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Center(
child:
Text(Provider.of<DataProvider>(context).myStudentData.rollNumber),
),
),
);
}
}
Then the error be like
======== Exception caught by widgets library =======================================================
The following NoSuchMethodError was thrown building StudentDashboard(dirty, dependencies: [_InheritedProviderScope<DataProvider>]):
The getter 'rollNumber' was called on null.
Receiver: null
Tried calling: rollNumber
The relevant error-causing widget was:
StudentDashboard file:///D:/Other/App/Flutter/my_ecampus/lib/views/screens/auth_screens/login_screen.dart:62:53
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
#1 StudentDashboard.build (package:my_ecampus/views/screens/main_screens/student_screens/student_dashboard.dart:38:69)
#2 StatelessElement.build (package:flutter/src/widgets/framework.dart:4701:28)
#3 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4627:15)
#4 Element.rebuild (package:flutter/src/widgets/framework.dart:4343:5)
...
====================================================================================================
E/flutter ( 7682): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: Looking up a deactivated widget's ancestor is unsafe.
E/flutter ( 7682): At this point the state of the widget's element tree is no longer stable.
E/flutter ( 7682): To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method.
E/flutter ( 7682): #0 Element._debugCheckStateIsActiveForAncestorLookup.<anonymous closure> (package:flutter/src/widgets/framework.dart:3906:9)
E/flutter ( 7682): #1 Element._debugCheckStateIsActiveForAncestorLookup (package:flutter/src/widgets/framework.dart:3920:6)
E/flutter ( 7682): #2 Element.getElementForInheritedWidgetOfExactType (package:flutter/src/widgets/framework.dart:3986:12)
E/flutter ( 7682): #3 Provider._inheritedElementOf (package:provider/src/provider.dart:324:34)
E/flutter ( 7682): #4 Provider.of (package:provider/src/provider.dart:281:30)
E/flutter ( 7682): #5 getStudentData (package:my_ecampus/business_view/services/database/getData_database.dart:19:12)
E/flutter ( 7682): <asynchronous suspension>
E/flutter ( 7682): #6 LoginScreen._login (package:my_ecampus/views/screens/auth_screens/login_screen.dart:60:9)
E/flutter ( 7682): <asynchronous suspension>
E/flutter ( 7682): #7 LoginScreen.build.<anonymous closure>.<anonymous closure> (package:my_ecampus/views/screens/auth_screens/login_screen.dart:198:31)
E/flutter ( 7682): #8 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:993:19)
E/flutter ( 7682): #9 _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:1111:38)
E/flutter ( 7682): #10 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:183:24)
E/flutter ( 7682): #11 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:598:11)
E/flutter ( 7682): #12 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:287:5)
E/flutter ( 7682): #13 BaseTapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:259:7)
E/flutter ( 7682): #14 GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:157:27)
E/flutter ( 7682): #15 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:362:20)
E/flutter ( 7682): #16 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:338:22)
E/flutter ( 7682): #17 RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:267:11)
E/flutter ( 7682): #18 GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:295:7)
E/flutter ( 7682): #19 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:240:7)
E/flutter ( 7682): #20 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:213:7)
E/flutter ( 7682): #21 _rootRunUnary (dart:async/zone.dart:1206:13)
E/flutter ( 7682): #22 _CustomZone.runUnary (dart:async/zone.dart:1100:19)
E/flutter ( 7682): #23 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1005:7)
E/flutter ( 7682): #24 _invoke1 (dart:ui/hooks.dart:265:10)
E/flutter ( 7682): #25 _dispatchPointerDataPacket (dart:ui/hooks.dart:174:5)
E/flutter ( 7682):
This is my main class and i am using multiprovider here.
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider<WidgetProvider>(
create: (context) => WidgetProvider()),
ChangeNotifierProvider<DataProvider>(
create: (context) => DataProvider()),
],
child: MaterialApp(
home: LoginScreen(),
),
);
}
}
This is where I call getStudentData function
void _login({String email, String password, BuildContext context}) async {
final loginResponse =
await loginDatabase(email: email, password: password, context: context);
if (loginResponse.isNotEmpty) {
final isStaff = email.contains(RegExp(r'.ce#srit.org$'));
if (isStaff == true) {
getStaffData(email, context);
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => StaffDashboard()));
} else {
getStudentData(email, context);//here is the getStudentData() function
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) => StudentDashboard()));
}
} else {
print('Login Failed from loginDatabase(){}');
}
}
The HTTP request is sent to the provider listen: false because it can not listen. So that you can call the method. That's why I designed it from scratch for you. I hope you understand. It will probably work if you do it as I did.
import 'package:http/http.dart' as http;
Future<StudentData> _getStudentData(String currentEmail, BuildContext context)async {
final _url = 'https://aaa.000webhostapp.com/getStudentData.php';
final response = await http.post(_url, body: {'email': currentEmail});
var data = response.body;
if (data.isEmpty) return null;
final decodedData = jsonDecode(data);
final myRollNumber = decodedData['roll_number'];
final myFirstName = decodedData['first_name'];
final myLastName = decodedData['last_name'];
final myStudentData = StudentData(
rollNumber: myRollNumber, firstName: myFirstName, lastName: myLastName);
return MystudentData;
}
class DataProvider extends ChangeNotifier {
StudentData myStudentData;
void getMyStudentData(StudentData studentData) {
myStudentData = studentData;
notifyListeners();
}
}
Future getMyStudentDataAsync() async {
StudentData result = await _getStudentData();
getMyStudentData(result);
}
class StudentDashboard extends StatelessWidget {
#override
void initState() {
super.initState(); getRequest();
}
future getRequest()async{
Provider.of<DataProvider>(context, listen: false)
.getMyStudentDataAsync();
}
#override
Widget build(BuildContext context) {
DataProvider _dataProvider = Provider.of<DataProvider>(context);
return SafeArea(
child: Scaffold(
body: Center(
child:
Text( _dataProvider.myStudentData.rollNumber),
),
),
);
}
}
I am creating a Flutter app that uses Google Authentication in Firebase.
The user can sign in with Google, but I need to keep the user logged in when the user launches the app again.
This is my code for main.dart
import 'package:flutter/material.dart';
import 'login_page.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
final FirebaseAuth _auth = FirebaseAuth.instance;
Future<void> _checkUserStatusGoogle() async {
await Firebase.initializeApp();
_auth
.authStateChanges()
.listen((User user) {
if (user == null) {
print('User is currently signed out!');
} else {
print('User is signed in!');
}
});
}
#override
void initState() {
Firebase.initializeApp().whenComplete(() {
_checkUserStatusGoogle().then((value) {
print('Check done done');
});
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Login',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: LoginPage(),
);
}
}
There is an error when launching the app with this code:
E/flutter (15566): [ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: [core/no-app] No Firebase App '[DEFAULT]' has been created - call Firebase.initializeApp()
E/flutter (15566): #0 MethodChannelFirebase.app (package:firebase_core_platform_interface/src/method_channel/method_channel_firebase.dart:118:5)
E/flutter (15566): #1 Firebase.app (package:firebase_core/src/firebase.dart:52:41)
E/flutter (15566): #2 FirebaseAuth.instance (package:firebase_auth/src/firebase_auth.dart:37:47)
E/flutter (15566): #3 new MyApp (package:flutter_faro_turnos/main.dart:10:43)
E/flutter (15566): #4 main (package:flutter_faro_turnos/main.dart:6:23)
E/flutter (15566): #5 _runMainZoned.<anonymous closure>.<anonymous closure> (dart:ui/hooks.dart:233:25)
E/flutter (15566): #6 _rootRun (dart:async/zone.dart:1190:13)
E/flutter (15566): #7 _CustomZone.run (dart:async/zone.dart:1093:19)
E/flutter (15566): #8 _runZoned (dart:async/zone.dart:1630:10)
E/flutter (15566): #9 runZonedGuarded (dart:async/zone.dart:1618:12)
E/flutter (15566): #10 _runMainZoned.<anonymous closure> (dart:ui/hooks.dart:225:5)
E/flutter (15566): #11 _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:301:19)
E/flutter (15566): #12 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)
What is wrong in my code?
EDIT:
New main.dart code:
import 'package:flutter/material.dart';
import 'login_page.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
void main() async {
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
final FirebaseAuth _auth = FirebaseAuth.instance;
Future<void> _checkUserStatusGoogle() async {
print('User is currently signed out!');
FirebaseAuth.instance
.authStateChanges()
.listen((User user) {
if (user == null) {
print('User is currently signed out!');
} else {
print('User is signed in!');
}
});
}
#override
void initState() {
print ("estoy en initstate");
Firebase.initializeApp().whenComplete(() {
_checkUserStatusGoogle().then((value) {
print('Check done done');
});
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Login',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: LoginPage(),
);
}
}
New error output:
E/flutter (18393): [ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: ServicesBinding.defaultBinaryMessenger was accessed before the binding was initialized.
E/flutter (18393): If you're running an application and need to access the binary messenger before `runApp()` has been called (for example, during plugin initialization), then you need to explicitly call the `WidgetsFlutterBinding.ensureInitialized()` first.
E/flutter (18393): If you're running a test, you can call the `TestWidgetsFlutterBinding.ensureInitialized()` as the first line in your test's `main()` method to initialize the binding.
E/flutter (18393): #0 defaultBinaryMessenger.<anonymous closure> (package:flutter/src/services/binary_messenger.dart:93:7)
E/flutter (18393): #1 defaultBinaryMessenger (package:flutter/src/services/binary_messenger.dart:106:4)
E/flutter (18393): #2 MethodChannel.binaryMessenger (package:flutter/src/services/platform_channel.dart:145:62)
E/flutter (18393): #3 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:151:35)
E/flutter (18393): #4 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:334:12)
E/flutter (18393): #5 MethodChannel.invokeListMethod (package:flutter/src/services/platform_channel.dart:347:40)
E/flutter (18393): #6 MethodChannelFirebase._initializeCore (package:firebase_core_platform_interface/src/method_channel/method_channel_firebase.dart:30:36)
E/flutter (18393): #7 MethodChannelFirebase.initializeApp (package:firebase_core_platform_interface/src/method_channel/method_channel_firebase.dart:75:13)
E/flutter (18393): #8 Firebase.initializeApp (package:firebase_core/src/firebase.dart:43:25)
E/flutter (18393): #9 main (package:flutter_faro_turnos/main.dart:7:18)
E/flutter (18393): #10 _runMainZoned.<anonymous closure>.<anonymous closure> (dart:ui/hooks.dart:233:25)
E/flutter (18393): #11 _rootRun (dart:async/zone.dart:1190:13)
E/flutter (18393): #12 _CustomZone.run (dart:async/zone.dart:1093:19)
E/flutter (18393): #13 _runZoned (dart:async/zone.dart:1630:10)
E/flutter (18393): #14 runZonedGuarded (dart:async/zone.dart:1618:12)
E/flutter (18393): #15 _runMainZoned.<anonymous closure> (dart:ui/hooks.dart:225:5)
E/flutter (18393): #16 _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:301:19)
E/flutter (18393): #17 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)
E/flutter (18393):
V/FA (18393): Inactivity, disconnecting from the service
This line of code is executing in during the construction of MyApp, before any of its methods are called:
final FirebaseAuth _auth = FirebaseAuth.instance
Since initializeApp() hasn't been invoked yet, this fails and throws the exception. You should consider calling initializeApp() during main instead, as shown here. The post gives several options. Personally, I would use main().
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
You only need the one call to initializeApp() when your app starts, so you should also remove the other calls in your code.
so i followed everthing from 'https://flutter.dev/docs/development/platform-integration/platform-channels?tab=android-channel-java-tab' but when I click the floating button in my device this error is shown.
[ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: MissingPluginException(No implementation found for method getBatteryLevel on channel battery)
E/flutter ( 4580): #0 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:159:7)
E/flutter ( 4580): <asynchronous suspension>
E/flutter ( 4580): #1 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:334:12)
E/flutter ( 4580): #2 _batteryState._getBatteryLevel (package:flutter_app/main.dart:45:37)
E/flutter ( 4580): #3 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:992:19)
E/flutter ( 4580): #4 _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:1098:38)
E/flutter ( 4580): #5 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:184:24)
E/flutter ( 4580): #6 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:524:11)
E/flutter ( 4580): #7 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:284:5)
E/flutter ( 4580): #8 BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:219:7)
E/flutter ( 4580): #9 PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:477:9)
E/flutter ( 4580): #10 PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:78:12)
E/flutter ( 4580): #11 PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:124:9)
E/flutter ( 4580): #12 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:377:8)
E/flutter ( 4580): #13 PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:122:18)
E/flutter ( 4580): #14 PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:108:7)
E/flutter ( 4580): #15 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:220:19)
E/flutter ( 4580): #16 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:200:22)
E/flutter ( 4580): #17 GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:158:7)
E/flutter ( 4580): #18 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:104:7)
E/flutter ( 4580): #19 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:88:7)
E/flutter ( 4580): #20 _rootRunUnary (dart:async/zone.dart:1206:13)
E/flutter ( 4580): #21 _CustomZone.runUnary (dart:async/zone.dart:1100:19)
E/flutter ( 4580): #22 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1005:7)
E/flutter ( 4580): #23 _invoke1 (dart:ui/hooks.dart:267:10)
E/flutter ( 4580): #24 _dispatchPointerDataPacket (dart:ui/hooks.dart:176:5)
E/flutter ( 4580):
Main.dart:-
import 'dart:ffi';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main(){
runApp(
MaterialApp(
home: battery()
)
);
}
class battery extends StatefulWidget {
#override
_batteryState createState() => _batteryState();
}
class _batteryState extends State<battery> {
static const platform = const MethodChannel('battery');
String _batteryLevel = 'error';
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('BatteryDetails'),
),
body: Center(
child: Column(
children: <Widget>[
FloatingActionButton.extended(onPressed: _getBatteryLevel, label: Text('Get battery info')),
Text(_batteryLevel),
],
)
)
);
}
Future<void> _getBatteryLevel() async{
String BatteryLevel;
try {
final int result = await platform.invokeMethod('getBatteryLevel');
BatteryLevel = 'battery Level is $result %.';
}on PlatformException catch (e){
BatteryLevel = "failed to get battery level: '&{e.message}'";
}
setState(() {
_batteryLevel = BatteryLevel;
});
}
}
MainActivity.java:-
package com.example.flutter_app;
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugin.common.MethodChannel;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "battery";
#Override
public void configureFlutterEngine(#NonNull FlutterEngine flutterEngine) {
super.configureFlutterEngine(flutterEngine);
new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
.setMethodCallHandler(
(call, result) -> {
// Note: this method is invoked on the main thread.
if (call.method.equals("getBatteryLevel")) {
int batteryLevel = getBatteryLevel();
if (batteryLevel != -1) {
result.success(batteryLevel);
} else {
result.error("UNAVAILABLE", "Battery level not available.", null);
}
} else {
result.notImplemented();
}
}
);
}
private int getBatteryLevel() {
int batteryLevel = -1;
if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
BatteryManager batteryManager = (BatteryManager) getSystemService(BATTERY_SERVICE);
batteryLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
} else {
Intent intent = new ContextWrapper(getApplicationContext()).
registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
batteryLevel = (intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100) /
intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
}
return batteryLevel;
}
}
i am new to flutter, can you help me also can anyone explain me what is happening in
public void configureFlutterEngine(#NonNull FlutterEngine flutterEngine) {
super.configureFlutterEngine(flutterEngine);
new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
.setMethodCallHandler(
(call, result)
this part of code.
thank you.
Based from the the error you got, you're getting a MissingPluginException from the method getBatteryLevel. This means the app is unable to find the method you're trying to call.
If you just tried running the app using hot reload, changes on platform-specific code might have not registered. Running the app using restart should usually solve the issue. If you're still having issues, you can print the log of the call.method being passed to the MethodChannel in your MainActivity.java to see if the method name from Flutter is being received as expected.
When using native features, always add the required dependencies in either Info.plist or AndroidManifest.xml and always re-install the whole app, hot-restart/reload won't always work if you all of a sudden implement some new code that accesses native device features.
I have written a test to check that a provider works as expected, however i get the following exception when checking that the context matches the providers context:
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following TestFailure object was thrown running a test:
Expected:
_InheritedProvderElement<AuthScreen>:<ChangeNotifierProvider<AuthScreen>-[GlobalKey#11403](value:
Instance of 'AuthScreen', listening to value)>
Actual:
_DefaultInheritedProviderScopeElement<AuthScreen>:<_DefaultInheritedProviderScope<AuthScreen>(value:
Instance of 'AuthScreen', listening to value)>
When the exception was thrown, this was the stack:
#4 main.<anonymous closure> (file:///home/hannes/Documents/StudioProjects/brf/test/Authentication/authenticate_test.dart:24:5)
<asynchronous suspension>
#5 testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart:140:29)
<asynchronous suspension>
#6 TestWidgetsFlutterBinding._runTestBody (package:flutter_test/src/binding.dart:699:19)
<asynchronous suspension>
#9 TestWidgetsFlutterBinding._runTest (package:flutter_test/src/binding.dart:679:14)
#10 AutomatedTestWidgetsFlutterBinding.runTest.<anonymous closure> (package:flutter_test/src/binding.dart:1079:24)
#16 AutomatedTestWidgetsFlutterBinding.runTest (package:flutter_test/src/binding.dart:1076:15)
#17 testWidgets.<anonymous closure> (package:flutter_test/src/widget_tester.dart:133:24)
#18 Declarer.test.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/declarer.dart:171:27)
<asynchronous suspension>
#19 Invoker.waitForOutstandingCallbacks.<anonymous closure> (package:test_api/src/backend/invoker.dart:242:15)
#24 Invoker.waitForOutstandingCallbacks (package:test_api/src/backend/invoker.dart:239:5)
#25 Declarer.test.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/declarer.dart:169:33)
#30 Declarer.test.<anonymous closure> (package:test_api/src/backend/declarer.dart:168:13)
#31 Invoker._onRun.<anonymous closure>.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/invoker.dart:392:25)
#45 _Timer._runTimers (dart:isolate-patch/timer_impl.dart:398:19)
#46 _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:429:5)
#47 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)
(elided 28 frames from class _FakeAsync, package dart:async, package dart:async-patch, and package stack_trace)
This was caught by the test expectation on the following line:
file:///home/hannes/Documents/StudioProjects/brf/test/Authentication/authenticate_test.dart line 24
The test description was:
AuthScreen provider changes value
════════════════════════════════════════════════════════════════════════════════════════════════════
Also, _childKey.currentContext is null. I don't know if that is related or if it's something else that I'm doing wrong.
I have tried to follow this guide, and my test looks like this:
import 'package:brf/models/auth_screen.dart';
import 'package:brf/screens/authenticate/authenticate.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
setUp(() {
AuthScreen();
});
testWidgets('AuthScreen provider changes value', (WidgetTester tester) async {
final _providerKey = GlobalKey();
final _childKey = GlobalKey();
BuildContext context;
await tester.pumpWidget(
MaterialApp(
home: ChangeNotifierProvider<AuthScreen>(
key: _providerKey,
create: (c) {
context = c;
return AuthScreen();
},
child: Authenticate(key: _childKey),
),
),
);
expect(context, equals(_providerKey.currentContext));
expect(Provider.of<AuthScreen>(_childKey.currentContext).showSignIn, true);
Provider.of<AuthScreen>(context, listen: false).switchScreen();
await Future.microtask(tester.pump);
expect(Provider.of<AuthScreen>(_childKey.currentContext).showSignIn, false);
});
}
And finally AuthScreen looks like this:
import 'package:flutter/material.dart';
class AuthScreen extends ChangeNotifier{
bool _showSignIn = true;
bool get showSignIn => _showSignIn;
void switchScreen(){
_showSignIn = !_showSignIn;
notifyListeners();
}
}
This is the error for the null context you passed
you this one:
Builder(builder: (context) => Widget here
Try like this where you want to pass the context:
MaterialApp(
home: Builder(builder: (context) => ChangeNotifierProvider<AuthScreen>(
key: _providerKey,
create: (c) {
context = c;
return AuthScreen();
},
child: Authenticate(key: _childKey),
),
),
);