Problem getting Firestore collection in flutter - flutter

I have a new project in Flutter working on an existing Firestore database.
I cannot seem to get the collection to surface in a list view (or even debugging). Firestore access seems Ok as I can use the Auth module Ok.
If I use the debugger and step into the collection get function, I can see the data is being returned, but the .then function is not being triggered. Am new to dart so am having trouble trying to figure out why the data is not being bubbled up to the .then()
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class InviteView extends StatelessWidget {
InviteView({Key? key}) : super(key: key);
List<String> ids = [];
#override
Widget build(BuildContext context) {
return Expanded(
child: FutureBuilder(
future: _getPlayers(),
builder: (context, snapshot) {
return ListView.builder(
itemCount: ids.length,
itemBuilder: (cxt, idx) {
return ListTile(
title: Text(ids[idx]),
);
},
);
},
),
);
}
Future<void> _getPlayers () async {
const source = Source.server;
await FirebaseFirestore.instance.collection('players').get(const GetOptions(source: source)).then(
(snapshot) => snapshot.docs.map((document) {
print(document.reference.id);
ids.add(document.reference.id);
}),
onError: (e) => print (e.toString())
);
}
}
Output from flutter doctor
[√] Flutter (Channel stable, 3.0.1, on Microsoft Windows [Version 10.0.22000.675], locale en-AU)
[√] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[√] Chrome - develop for the web
[X] Visual Studio - develop for Windows
X Visual Studio not installed; this is necessary for Windows development.
Download at https://visualstudio.microsoft.com/downloads/.
Please install the "Desktop development with C++" workload, including all of its default components
[√] Android Studio (version 2021.1)
[√] Android Studio (version 2021.2)
[√] Android Studio (version 4.1)
[√] VS Code (version 1.65.2)
[√] VS Code, 64-bit edition (version 1.32.3)
[√] Connected device (3 available)
[√] HTTP Host Availability
using cloud_firestore: ^3.1.17

Does this help:
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class InviteView extends StatelessWidget {
InviteView({Key? key}) : super(key: key);
List<String> ids = [];
#override
Widget build(BuildContext context) {
return Expanded(
child: FutureBuilder<Widget>(
future: _getPlayers(),
builder: (context, snapshot) {
if (!snapshot.hasData) return const Text('Oh no!');
return snapshot.data!;
},
),
);
}
Future<ListView> _getPlayers() async {
var snap = await FirebaseFirestore.instance.collection('players').get();
return ListView(
children: snap.docs
.map((doc) => ListTile(
title: Text(doc.reference.id),
))
.toList());
}
}

Related

flutter-mapbox-gl MapBox paints over AppBar and NavBar :(

I try to get MapBox to work properly in Flutter, but it somehow seems to initially open to big and paint over AppBar and NavBar. After that it seems that it moves into the correct position, but the AppBar and NavBar are now ruined :(
Any way to fix this?
Related Git Issue here
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 3.0.1, on Microsoft Windows [Version 10.0.19044.1706], locale en-NZ)
[√] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
[√] Chrome - develop for the web
[√] Visual Studio - develop for Windows (Visual Studio Community 2022 17.2.0)
[√] Android Studio (version 2021.2)
[√] VS Code (version 1.67.2)
[√] Connected device (4 available)
[√] HTTP Host Availability
environment:
sdk: '>=2.17.0 <3.0.0'
dependencies:
collection:
cupertino_icons: ^1.0.2
flutter:
sdk: flutter
flutter_easyloading: ^3.0.3
get: ^4.6.3
http:
logger: ^1.1.0
mapbox_gl: ^0.16.0
oauth2_client: ^2.4.0
syncfusion_flutter_calendar: ^20.1.57
dev_dependencies:
flutter_lints: ^2.0.0
flutter_test:
sdk: flutter
flutter:
uses-material-design: true
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:mapbox_gl/mapbox_gl.dart';
import '../services/item.dart';
class MapControl extends StatefulWidget {
const MapControl({Key? key}) : super(key: key);
#override
State<StatefulWidget> createState() => MapControlState();
}
class MapControlState extends State<MapControl> {
final itemService = Get.find<ItemService>();
#override
void initState() {
super.initState();
}
MapboxMapController? mapController;
_onMapCreated(MapboxMapController controller) {
mapController = controller;
}
_onStyleLoadedCallback() {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: const Text("Style loaded :)"),
backgroundColor: Theme.of(context).primaryColor,
duration: const Duration(seconds: 1),
));
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: MapboxMap(
styleString: MapboxStyles.LIGHT,
accessToken: 'xxxxxxxxxxxxxxxxx',
onMapCreated: _onMapCreated,
initialCameraPosition: const CameraPosition(target: LatLng(0.0, 0.0)),
onStyleLoadedCallback: _onStyleLoadedCallback,
));
}
}

Cannot send verification email FIREBASE AUTH

So I made a testing Flutter app because I'm having problems with my bigger one and I wanted to try isolate the problem.
Whenever I try to call user.sendEmailVerification() it never actually sends the email. I added .then afterwards and checked if it did send and it says it did but I've tried everything so I'm hoping someone here can help me out!!
main.dart
import 'package:emailverifytest/verify.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'firebase_options.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(home: verify());
}
}
verify.dart
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter/src/foundation/key.dart';
import 'package:flutter/src/widgets/framework.dart';
class verify extends StatelessWidget {
const verify({Key? key}) : super(key: key);
void runTest() async {
try {
// await FirebaseAuth.instance.createUserWithEmailAndPassword(
// email: 'example#gmail.com', password: 'password');
await FirebaseAuth.instance
.signInWithEmailAndPassword(
email: 'example#gmail.com', password: 'password')
.then((value) async {
await FirebaseAuth.instance.currentUser!.sendEmailVerification();
print('sent');
});
// User? user = await FirebaseAuth.instance.currentUser;
// if (user != null && !user.emailVerified) {
// await user.sendEmailVerification();
// print("here");
// }
} on FirebaseAuthException catch (e) {
print(e.code);
}
}
#override
Widget build(BuildContext context) {
runTest();
return const Scaffold();
}
}
Flutter doctor
[✓] Flutter (Channel stable, 3.0.1, on macOS 12.4 21F79 darwin-arm, locale en-NZ)
• Flutter version 3.0.1 at /Users/kaneviggers/Documents/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision fb57da5f94 (13 days ago), 2022-05-19 15:50:29 -0700
• Engine revision caaafc5604
• Dart version 2.17.1
• DevTools version 2.12.2
[✗] Android toolchain - develop for Android devices
✗ Unable to locate Android SDK.
Install Android Studio from: https://developer.android.com/studio/index.html
On first launch it will assist you in installing the Android SDK components.
(or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions).
If the Android SDK has been installed to a custom location, please use
`flutter config --android-sdk` to update to that location.
[✓] Xcode - develop for iOS and macOS (Xcode 13.4)
• Xcode at /Applications/Xcode.app/Contents/Developer
• CocoaPods version 1.11.3
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[!] Android Studio (not installed)
• Android Studio not found; download from https://developer.android.com/studio/index.html
(or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions).
[✓] VS Code (version 1.67.2)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.42.0
I'll be online for the rest of the day, so I'll be quick to reply!
Cheers
-Kane

How to properly put multiple VideoPlayer into a PageView in flutter?

I'm trying to create an app where I can switch videos with swipes (similar to TikTok). My current implementation looks like this:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
List<String> urls = [
"https://movietrailers.apple.com/movies/oscilloscope/relaxer/relaxer-trailer-1_720p.mov",
"https://movietrailers.apple.com/movies/sony_pictures/the-front-runner/front-runner-trailer-1_720p.mov",
"https://movietrailers.apple.com/movies/independent/cant-stop-wont-stop-a-bad-boy-story/cant-stop-wont-stop-trailer-1_720p.mov",
"https://movietrailers.apple.com/movies/independent/at-first-light/at-first-light-trailer-1_720p.mov"
];
return MaterialApp(
home: PageView.builder(
itemBuilder: (ctx, index) => VideoScreen(url: urls[index]),
itemCount: urls.length,
scrollDirection: Axis.vertical,
),
);
}
}
class VideoScreen extends StatefulWidget {
final String url;
const VideoScreen({Key? key, required this.url}) : super(key: key);
#override
_VideoScreenState createState() => _VideoScreenState();
}
class _VideoScreenState extends State<VideoScreen> {
late VideoPlayerController controller;
void initController() async {
controller = VideoPlayerController.network(widget.url);
await controller.initialize();
controller.play();
}
#override
void initState() {
initController();
super.initState();
}
#override
Widget build(BuildContext context) {
if (controller.value.isInitialized) {
return const CircularProgressIndicator();
}
return SizedBox(
height: double.infinity,
child: AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: VideoPlayer(controller),
),
);
}
}
However, each initialization call o VideoPlayerController entails a complete freeze of the application for the duration of the video download. During this, I am not able to perform any actions in the application.
I'm using the newest version of package in my pubspec.yaml: video_player: ^2.2.16.
Here is the output of the flutter doctor command:
% flutter doctor -v
[✓] Flutter (Channel stable, 2.5.1, on macOS 12.1 21C52 darwin-arm, locale ru-RU)
• Flutter version 2.5.1 at /Users/rkfcccccc/documents/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision ffb2ecea52 (5 months ago), 2021-09-17 15:26:33 -0400
• Engine revision b3af521a05
• Dart version 2.14.2
[!] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
• Android SDK at /Users/rkfcccccc/Library/Android/sdk
✗ cmdline-tools component is missing
Run `path/to/sdkmanager --install "cmdline-tools;latest"`
See https://developer.android.com/studio/command-line for more details.
✗ Android license status unknown.
Run `flutter doctor --android-licenses` to accept the SDK licenses.
See https://flutter.dev/docs/get-started/install/macos#android-setup for more details.
[✓] Xcode - develop for iOS and macOS
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 13.2.1, Build version 13C100
• CocoaPods version 1.11.2
[✗] Chrome - develop for the web (Cannot find Chrome executable at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome)
! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.
[!] Android Studio (not installed)
• Android Studio not found; download from https://developer.android.com/studio/index.html
(or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions).
[✓] VS Code (version 1.63.2)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.32.0
[✓] Connected device (1 available)
• rkfcccccc (mobile) iOS 15.2.1 19C63
Consider making use of state management such as Provider to handle the logic to initialize incoming indices and play current index. The same will be used to pause/remove the controller once the index is changed to a succeeding or preceding index.
just make sure you dispose your controller inside your VideoScreen
#override
void dispose() {
_controller.dispose();
super.dispose();
}

Flutter error: Unhandled Exception: HandshakeException: Handshake error in client

I'm trying to test my flutter app locally, connecting to my API locally. I have that application running on localhost:5000, and this is the code of a simple login form I've created.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'groups.dart';
import 'signup.dart';
class Token {
final String userToken;
Token({this.userToken});
factory Token.fromJson(Map<String, dynamic> json) {
print(json);
return Token(
userToken: json['title'],
);
}
}
class Login extends StatefulWidget {
Login({Key key}) : super(key: key);
#override
LoginState createState() => LoginState();
}
class LoginState extends State<Login> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
var userData = {};
void updateField(String value, String field) {
setState(() {
userData = {
...userData,
'$field': value,
};
});
}
Future<http.Response> sendLogin(user) {
final response = http.post(
Uri.parse('https://10.0.2.2:5000/api/User/Login'),
headers: <String, String>{
'Content-Type': 'application/json',
},
body: jsonEncode(user),
);
print(response);
return response;
}
#override
Widget build(BuildContext context) {
return Material(
child: Column(children: <Widget>[
Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TextFormField(), // these 2 form fields are commented out because they're already confirmed
TextFormField(), // to be working perfectly.
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: ElevatedButton(
onPressed: () {
if (_formKey.currentState.validate()) {
sendLogin(userData);
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => Groups(),
));
}
},
child: Text('Submit'),
),
),
],
),
),
ElevatedButton(), // removed inside because it's a link to another page
);
}
}
I've looked at this link here how to solve flutter CERTIFICATE_VERIFY_FAILED error while performing a POST request?
That link led me to include more in my main.dart file, at least for testing purposes, ending that like this
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:mobile_v2/Packages/user-check.dart';
void main() {
HttpOverrides.global = new MyHttpOverrides();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Gathering',
home: UserCheck(),
);
}
}
class MyHttpOverrides extends HttpOverrides{
#override
HttpClient createHttpClient(SecurityContext context){
return super.createHttpClient(context)
..badCertificateCallback = (X509Certificate cert, String host, int port)=> true;
}
}
After making these changes, I ran a flutter pub get, just to be safe, and yet I'm still having the same issues. I've looked through most of the answers in that post, and it still gives the same result. Any other possible answers would be appreciated. Thank you. (flutter doctor below as well)
[√] Flutter (Channel stable, 2.0.5, on Microsoft Windows [Version 10.0.19041.985], locale en-US)
• Flutter version 2.0.5 at C:\src\flutter\flutter
• Framework revision adc687823a (5 weeks ago), 2021-04-16 09:40:20 -0700
• Engine revision b09f014e96
• Dart version 2.12.3
[√] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
• Android SDK at C:\Users\ocdam\AppData\Local\Android\sdk
• Platform android-30, build-tools 30.0.3
• Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
• All Android licenses accepted.
[√] Chrome - develop for the web
• Chrome at C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
[√] Android Studio (version 4.1.0)
• Android Studio at C:\Program Files\Android\Android Studio
• Flutter plugin can be installed from:
https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
[√] IntelliJ IDEA Community Edition (version 2019.3)
• IntelliJ at C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2019.3
• Flutter plugin can be installed from:
https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
https://plugins.jetbrains.com/plugin/6351-dart
[√] VS Code (version 1.56.2)
• VS Code at C:\Users\ocdam\AppData\Local\Programs\Microsoft VS Code
• Flutter extension version 3.22.0
[√] Connected device (3 available)
• sdk gphone x86 arm (mobile) • emulator-5554 • android-x86 • Android 11 (API 30) (emulator)
• Chrome (web) • chrome • web-javascript • Google Chrome 90.0.4430.212
• Edge (web) • edge • web-javascript • Microsoft Edge 90.0.818.49
• No issues found!

location onChange function keeps getting called even when location is static (Flutter)

I am working with the Location 3.0.1 package in Flutter. I want to listen for location changes. My code (which is taken pretty much entirely from the github example for this package) is as follows:
class _HomePageState extends State<HomePage> {
StreamSubscription<LocationData> locationSubscription;
final Location location = new Location();
LocationData _locationData;
String _error;
var popupData;
PermissionStatus _permissionGranted;
_checkPermissions() async {
PermissionStatus permissionGrantedResult = await location.hasPermission();
setState(() {
_permissionGranted = permissionGrantedResult;
});
}
_requestPermission() async {
if (_permissionGranted != PermissionStatus.GRANTED) {
PermissionStatus permissionRequestedResult =
await location.requestPermission();
print(permissionRequestedResult);
setState(() {
_permissionGranted = permissionRequestedResult;
});
if (permissionRequestedResult != PermissionStatus.GRANTED) {
return;
} else{
_loadLocation();
}
}
else{
_loadLocation();
}
}
Future<void> _listenLocation() async {
locationSubscription =
location.onLocationChanged().handleError((dynamic err) {
setState(() {
_error = err.code;
});
locationSubscription.cancel();
}).listen((LocationData currentLocation) {
setState(() {
_error = null;
_locationData = currentLocation;
});
});
}
void _loadLocation() async {
_locationData = await location.getLocation();
_listenLocation();
}
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
if(_locationData == null){
_checkPermissions();
_requestPermission();
}
. . .
However, the stream subscription keeps getting triggered quite frequently (about once ever 2-3 seconds) (which causes setState to be called, and the whole screen to be rebuilt) even when the location is not changing (I am running this code on my emulator, so location should be static). Does anyone know why this is happening and how to fix it?
Output of flutter doctor:
[✓] Flutter (Channel stable, v1.12.13+hotfix.5, on Mac OS X 10.15.2 19C57, locale en-US)
• Flutter version 1.12.13+hotfix.5 at /Users/foo/development/flutter
• Framework revision 27321ebbad (4 months ago), 2019-12-10 18:15:01 -0800
• Engine revision 2994f7e1e6
• Dart version 2.7.0
[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
• Android SDK at /Users/foo/Library/Android/sdk
• Android NDK location not configured (optional; useful for native profiling support)
• Platform android-29, build-tools 28.0.3
• Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 11.3)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 11.3, Build version 11C29
• CocoaPods version 1.8.4
[✓] Android Studio (version 3.5)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin version 39.0.3
• Dart plugin version 191.8423
• Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
[✓] IntelliJ IDEA Ultimate Edition (version 2019.1.4)
• IntelliJ at /Applications/IntelliJ IDEA.app
• Flutter plugin version 38.1.3
• Dart plugin version 191.8593
[✓] Connected device (2 available)
• Android SDK built for x86 • emulator-5554 • android-x86 • Android 9 (API 28) (emulator)
• iPhone 11 Pro Max • B3536B50-C435-4442-9CF4-69D470B979CA • ios •
com.apple.CoreSimulator.SimRuntime.iOS-13-3 (simulator)
• No issues found!
If someone could just give me a snippet of code showing how to properly listen for updates, that would also be helpful (i.e. I'm not set on my code looking exactly like this).
You can copy paste run full code below
Because you put code in Widget build cause this issue
You can reference this https://medium.com/flutter-community/build-a-location-service-in-flutter-367a1b212f7a to build a Location Service
I made few change, you can directly see full code
You can use StreamProvider instead of await location.getLocation in Widget build
Youn can directly use location.requestPermission instead of Permission Handler
code snippt
return StreamProvider<UserLocation>(
create: (context) => LocationService().locationStream,
...
LocationService() {
// Request permission to use location
location.requestPermission().then((permissionStatus) {
if (permissionStatus == PermissionStatus.granted) {
// If granted listen to the onLocationChanged stream and emit over our controller
location.onLocationChanged.listen((locationData) {
working demo
full code
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:location/location.dart';
import 'dart:async';
class LocationService {
UserLocation _currentLocation;
var location = Location();
StreamController<UserLocation> _locationController =
StreamController<UserLocation>();
Stream<UserLocation> get locationStream => _locationController.stream;
LocationService() {
// Request permission to use location
location.requestPermission().then((permissionStatus) {
if (permissionStatus == PermissionStatus.granted) {
// If granted listen to the onLocationChanged stream and emit over our controller
location.onLocationChanged.listen((locationData) {
if (locationData != null) {
_locationController.add(UserLocation(
latitude: locationData.latitude,
longitude: locationData.longitude,
));
}
});
}
});
}
Future<UserLocation> getLocation() async {
try {
var userLocation = await location.getLocation();
_currentLocation = UserLocation(
latitude: userLocation.latitude,
longitude: userLocation.longitude,
);
} on Exception catch (e) {
print('Could not get location: ${e.toString()}');
}
return _currentLocation;
}
}
void main() {
runApp(MyApp());
}
class UserLocation {
final double latitude;
final double longitude;
UserLocation({this.latitude, this.longitude});
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return StreamProvider<UserLocation>(
create: (context) => LocationService().locationStream,
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: HomeView(),
)),
);
}
}
class HomeView extends StatelessWidget {
const HomeView({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
var userLocation = Provider.of<UserLocation>(context);
return Center(
child: Text(
'Location: Lat${userLocation?.latitude}, Long: ${userLocation?.longitude}'),
);
}
}