I'd like to have https:// automatically attached to the link - flutter

When I tried to retrieve img from the website, the link started with /upload/.... instead of https://.
I want to have https:// written automatically in front of me. What should I do?
homepage:
<div class="photo_list">
<ul>
<li>
<a href="/yongwon-h/na/ntt/selectNttInfo.do?nttSn=85189591&mi=73747">
<img src="/upload/bbs/files/2021/hgschl/yongwon-h/ntt/62865/ntt_85189591/thumb/thumb_img_9028b523-7bfb-466f-848c-65870a93b99c1616411595463.jpg" onerror="this.src='/images/co/na/noImg.gif'" alt="대표이미지">
<p>책을 가까이, 책은 나의 친구!! 아침독서의 생활화!!!</p>
<span>
2021.03.22
<br> 조회 6
</span>
</a>
</li>
</ul>
</div>
MY CODE:
import 'package:flutter/material.dart';
import 'package:flutter_share/flutter_share.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
import 'package:http/http.dart' as http;
import 'package:html/dom.dart' as dom;
import 'package:html/parser.dart' as parser;
import 'package:url_launcher/url_launcher.dart';
class UpdatePost extends StatefulWidget {
#override
_UpdatePostState createState() => _UpdatePostState();
}
class _UpdatePostState extends State<UpdatePost> {
List<String> title = List();
List<String> post = List();
List<String> link = List();
List<String> image = List();
void _getDataFromWeb() async {
Uri uri = Uri.parse(
'http://yongwon-h.gne.go.kr/yongwon-h/na/ntt/selectNttList.do?mi=73747&&bbsId=62865');
final response = await http.get(uri);
dom.Document document = parser.parse(response.body);
final link2 = document.getElementsByClassName('photo_list');
final content = document.getElementsByClassName('photo_list');
final elements = document.getElementsByClassName('photo_list');
final ImageElement = document.getElementsByClassName('photo_list');
setState(() {
title = elements
.map((element) => element.getElementsByTagName("p")[0].innerHtml)
.toList();
post = content
.map((element) => element.getElementsByTagName("span")[0].innerHtml)
.toList();
link = link2
.map((element) =>
element.getElementsByTagName("a")[0].attributes['href'])
.toList();
image = ImageElement.map((element) =>
element.getElementsByTagName("img")[0].attributes['src']).toList();
});
}
Future<void> share(dynamic link, String title) async {
await FlutterShare.share(
title: 'Codding Application',
text: title,
linkUrl: link,
chooserTitle: 'Where You Want to Share');
}
#override
void initState() {
_getDataFromWeb();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black87,
body: post.length == 0
? Text("No data", style: TextStyle(color: Colors.white))
: ListView.builder(
itemCount: post.length,
itemBuilder: (context, index) {
return AnimationConfiguration.staggeredList(
position: index,
duration: const Duration(milliseconds: 375),
child: SlideAnimation(
child: FadeInAnimation(
child: GestureDetector(
onTap: () async {
dynamic url = link[index];
if (await canLaunch(url))
launch(url);
else {
print('error');
}
},
child: Padding(
padding: const EdgeInsets.all(10),
child: Card(
child: Container(
color: Colors.black87,
child: Column(
children: <Widget>[
Container(
child: Image.network(
image[index],
scale: 0.1,
),
),
Align(
alignment: Alignment.centerLeft,
child: Text(
title[index],
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.red,
fontSize: 20,
),
),
),
SizedBox(height: 15),
Text(
post[index],
style: TextStyle(
color: Colors.white,
),
),
Row(
children: <Widget>[
FlatButton(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(5.0),
side: BorderSide(color: Colors.white)),
onPressed: () {
share(link[index], title[index]);
},
child: Text(
"Share With Friends",
style: TextStyle(
color: Colors.red,
),
),
),
SizedBox(width: 10),
FlatButton(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(5.0),
side: BorderSide(color: Colors.white)),
onPressed: () async {
dynamic url = link[index];
if (await canLaunch(url))
launch(url);
else {
print('error');
}
},
child: Text(
"Explore Post",
style: TextStyle(
color: Colors.red,
),
),
),
],
),
],
),
),
),
),
))),
);
},
),
);
}
}
conclusion:
I want to automatically put http://yongwon-h.gne.go.kr in front of the called tag a.
I feel like I'm asking repeatedly, but I really don't know. I googled thousands of sites in a week. Please help me.

import 'dart:async';
import 'package:wnetworking/wnetworking.dart';
final Map<String, Map<String, dynamic>> reDic = {
'notices' : {
'relPath' : '/yongwon-h/main.do',
're' : <RegExp>[
RegExp(r'<h2 class="tit_1">(.|\n|\r|\u2028|\u2029)*?<h2 class="tit_2">'),
RegExp(r'<li><a.+>(.+)<\/a>(.|\n|\r|\u2028|\u2029)*?(\d{4}\.\d\d\.\d\d)'),
]
},
'images' : {
'relPath' : '/yongwon-h/na/ntt/selectNttList.do?mi=73747&&bbsId=62865',
're' : <RegExp>[
RegExp(r'<div class="photo_list">(.|\n|\r|\u2028|\u2029)*?<!-- \/\/게시판 리스트'),
RegExp(r'<img src="(.+)" onerror'),
]
},
};
class Yongwon {
static const _baseUrl = 'http://yongwon-h.gne.go.kr';
static FutureOr<void> fetchNoticies() async {
await _getHTMLObjects(
reDic['notices']!['relPath'],
reDic['notices']!['re']![0],
reDic['notices']!['re']![1],
)
.then((matches) {
if (matches != null) {
matches.forEach((match) => print('${match.group(1)} ..... ${match.group(3)}'));
}
});
}
static FutureOr<void> fetchImages() async {
await _getHTMLObjects(
reDic['images']!['relPath'],
reDic['images']!['re']![0],
reDic['images']!['re']![1],
)
.then((matches) {
if (matches != null) {
matches.forEach((match) => print('$_baseUrl${match.group(1)}'));
}
});
}
static Future<Iterable<RegExpMatch>?> _getHTMLObjects(String relPath, RegExp reContainer, RegExp reObjects) async {
var page = await NetService.getRaw(_baseUrl + relPath)
.whenComplete(() => print('Page done.\n'));
if (page != null) {
final objectsPane = reContainer.firstMatch(page)!.group(0);
if (objectsPane != null) {
return Future.value(reObjects.allMatches(objectsPane));
}
}
return null;
}
}
void main(List<String> args) async {
await Yongwon.fetchImages();
print('\nJob done!');
}
Netservice (partial code):
class NetService {
static Future<String?> getRaw(String url, {int okCode = 200}) {
return http.get(Uri.parse(url))
.then((response) {
if (response.statusCode == okCode) {
return response.body;
}
PrintService.showDataNotOK(response);
return null;
})
.catchError((err) => PrintService.showError(err));
}
}
Result:
Page done.
http://yongwon-h.gne.go.kr/upload/bbs/files/2021/hgschl/yongwon-h/ntt/62865/ntt_85189591/thumb/thumb_img_9028b523-7bfb-466f-848c-65870a93b99c1616411595463.jpg
http://yongwon-h.gne.go.kr/upload/bbs/files/2021/hgschl/yongwon-h/ntt/62865/ntt_85169237/thumb/thumb_img_0fe7d01b-6941-4468-8623-088af971fbf21616047569744.jpg
http://yongwon-h.gne.go.kr/upload/bbs/files/2021/hgschl/yongwon-h/ntt/62865/ntt_85148970/thumb/thumb_img_67ae1c34-cd49-4af4-8a68-cacec672c84d1615859096270.jpg
http://yongwon-h.gne.go.kr/upload/bbs/files/2021/hgschl/yongwon-h/ntt/62865/ntt_85041266/thumb/thumb_img_ddc5097b-ae4e-4190-b0b8-1aa88cf78e491614223854604.jpg
http://yongwon-h.gne.go.kr/upload/bbs/files/2021/hgschl/yongwon-h/ntt/62865/ntt_85039068/thumb/thumb_img_f5c77ec4-a448-44b0-b5b1-61079be18eb61614145925749.jpg
http://yongwon-h.gne.go.kr/upload/bbs/files/2021/hgschl/yongwon-h/ntt/62865/ntt_85002051/thumb/thumb_img_0df44e4d-9872-4605-a94f-32b3004bc42a1612331543446.jpg
http://yongwon-h.gne.go.kr/upload/bbs/files/2021/hgschl/yongwon-h/ntt/62865/ntt_84955511/thumb/thumb_img_de1fc864-2689-4917-85bc-b5d714040b1f1610248949513.jpg
http://yongwon-h.gne.go.kr/upload/bbs/files/2021/hgschl/yongwon-h/ntt/62865/ntt_84950100/thumb/thumb_img_cd3270ee-7bd0-4601-81fc-2de446903e281609919353000.jpg
http://yongwon-h.gne.go.kr/upload/bbs/files/2021/hgschl/yongwon-h/ntt/62865/ntt_84950096/thumb/thumb_img_0eee718a-a2de-4182-a0d9-f97de17d98741609919173296.jpg
Job done!

Related

Delete profile in firebase flutter

I need to delete the users profile from firebase, thing is I have 3 collections petfiles, petsdetails and users which need to be deleted. As in when a user signs up, they can create a pet and create records for their pet. But when having to delete the user, it should delete all the pets and records the pet has (it could be up to any amount)
I havent tried anything as I dont really know how to solve this but this is my code
import 'dart:io';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:image_picker/image_picker.dart';
import 'package:vet_bookr/oScreens/petFiles.dart';
import '../constant.dart';
class UserDetails extends StatefulWidget {
UserDetails({Key? key, required this.details}) : super(key: key);
Map<String, dynamic> details;
#override
State<UserDetails> createState() => _UserDetailsState();
}
class _UserDetailsState extends State<UserDetails> {
List<String> labels = ["Email", "Phone Number"];
bool editableText = false;
String imageUrl = "";
List<String> petIds = [];
#override
void initState() {
// TODO: implement initState
nameController.text = widget.details["name"];
ageController.text = widget.details["age"];
super.initState();
}
Future<void> uploadImages({required String path}) async {
try {
final imageRef = storageRef.child(
"Users/${FirebaseAuth.instance.currentUser?.uid}/${widget.details["id"]}");
await imageRef.putFile(File(path));
imageUrl = await imageRef.getDownloadURL();
setState(() {});
//print(imageRef.getDownloadURL());
} on FirebaseException catch (e) {
print("Function does work");
SnackBar snackBar = SnackBar(content: Text(e.message!));
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
}
bool isLoading = false;
final nameController = TextEditingController();
final ageController = TextEditingController();
XFile? profilePic;
ImagePicker imagePicker = ImagePicker();
final storageRef = FirebaseStorage.instance.ref();
TextEditingController controllerChanger(index) {
if (index == 0) {
return nameController;
}
if (index == 1) {
return ageController;
}
return TextEditingController();
}
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
},
child: Scaffold(
appBar: AppBar(
systemOverlayStyle: SystemUiOverlayStyle.dark,
backgroundColor: Colors.transparent,
elevation: 0,
leading: IconButton(
icon: Icon(
Icons.arrow_back,
color: Colors.black,
),
onPressed: () {
Navigator.pop(context);
},
),
actions: [
Padding(
padding: EdgeInsets.only(right: 5.sp),
child: PopupMenuButton(
icon: Icon(
Icons.more_vert,
color: Colors.black,
),
itemBuilder: (context) {
return [
PopupMenuItem<int>(
value: 0,
child: Text("Edit Profile"),
),
PopupMenuItem<int>(
value: 1,
child: Text("Delete Profile"),
),
];
},
onSelected: (value) async {
if (value == 0) {
setState(() {
editableText = true;
});
print(editableText);
} else if (value == 1) {
setState(() {
isLoading = true;
});
final ref = storageRef.child(
"Users/${FirebaseAuth.instance.currentUser?.uid}/${widget.details["id"]}");
await ref.delete();
await FirebaseFirestore.instance
.collection("users")
.doc(FirebaseAuth.instance.currentUser?.uid)
.delete();
DocumentSnapshot<Map<dynamic, dynamic>> snap =
await FirebaseFirestore.instance
.collection("users")
.doc(FirebaseAuth.instance.currentUser?.uid)
.get();
await FirebaseFirestore.instance
.collection("petDetails")
.doc(FirebaseAuth.instance.currentUser?.uid)
.update({
'pets': FieldValue.arrayRemove(snap.data()!["pets"]!),
});
await FirebaseFirestore.instance
.collection("users")
.doc(FirebaseAuth.instance.currentUser?.uid)
.update({
'pets': FieldValue.arrayUnion(snap.data()!["pets"]!),
});
setState(() {
isLoading = false;
});
Navigator.pop(context);
}
},
))
],
),
extendBodyBehindAppBar: true,
backgroundColor: kBackgroundColor,
body: isLoading
? Container(
width: 1.sw,
height: 0.4.sh,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
height: 15.sp,
width: 15.sp,
child: CircularProgressIndicator(
strokeWidth: 2,
color: Color(0xffFF8B6A),
),
),
],
),
)
: SafeArea(
child: Container(
//alignment: Alignment.center,
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(15.sp),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
// sBox(h: 10),
Text(
'Pet Information',
style: TextStyle(
color: Color(0xffF08519), fontSize: 0.05.sw),
),
// myPetTile()
SizedBox(
height: 0.05.sh,
),
Stack(
children: [
CircleAvatar(
radius: 0.095.sh,
backgroundColor: Color(0xffFF8B6A),
backgroundImage: profilePic == null
? NetworkImage(
widget.details["profilePicture"],
)
: null,
child: profilePic == null
? Container(
width: 0,
height: 0,
)
: ClipRRect(
borderRadius:
BorderRadius.circular(100),
child: Image.file(
File(
"${profilePic?.path}",
),
),
),
),
editableText
? Positioned(
right: 0.025.sw,
bottom: 0.005.sh,
child: GestureDetector(
onTap: () async {
profilePic = await ImagePicker()
.pickImage(
source: ImageSource.gallery);
setState(() {});
},
child: CircleAvatar(
backgroundColor: Color(0xffFF8B6A),
radius: 0.02.sh,
child: Icon(
Icons.camera_alt_outlined,
size: 0.05.sw,
color: Colors.white,
),
),
),
)
: Container(
width: 0,
height: 0,
)
],
),
SizedBox(
height: 0.02.sh,
),
...List.generate(
2,
(index) => Padding(
padding: EdgeInsets.only(
top: 0.02.sh, left: 0.05.sw, right: 0.05.sw),
child: TextField(
enabled: editableText,
controller: controllerChanger(index),
style: TextStyle(fontSize: 0.017.sh),
cursorColor: Colors.black,
decoration: InputDecoration(
label: Text(labels[index],
style: TextStyle(fontSize: 0.02.sh)),
labelStyle: TextStyle(color: Colors.black54),
focusedBorder: OutlineInputBorder(
borderRadius:
BorderRadius.circular(10.sp),
borderSide:
BorderSide(color: Color(0xffFF8B6A))),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.sp),
),
enabledBorder: OutlineInputBorder(
borderRadius:
BorderRadius.circular(10.sp),
borderSide:
BorderSide(color: Color(0xffFF8B6A))),
contentPadding:
EdgeInsets.symmetric(horizontal: 10.sp),
hintStyle: TextStyle(color: Colors.grey),
),
),
),
),
buttonWidget()
],
),
),
),
),
),
),
);
}
bool isLoadingEdit = false;
Widget buttonWidget() {
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
width: 0.4.sw,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
padding: EdgeInsets.zero,
backgroundColor: Color(0xffFF8B6A),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.sp),
),
),
onPressed: () async {
if (editableText) {
setState(() {
isLoadingEdit = true;
});
if (profilePic != null) {
final ref = storageRef.child(
"Users/${FirebaseAuth.instance.currentUser?.uid}/${widget.details["id"]}");
await ref.delete();
await uploadImages(path: profilePic!.path);
}
await FirebaseFirestore.instance
.collection("petsDetails")
.doc(widget.details["id"])
.update({
'name': nameController.text,
'age': ageController.text,
'breed': breedController.text,
'weight': weightController.text,
'profilePicture': profilePic != null
? imageUrl
: widget.details["profilePicture"],
'lastVaccinationDate':
widget.details["lastVaccinationDate"]
});
DocumentSnapshot<Map<String, dynamic>> snap =
await FirebaseFirestore.instance
.collection("users")
.doc(FirebaseAuth.instance.currentUser?.uid)
.get();
await FirebaseFirestore.instance
.collection("users")
.doc(FirebaseAuth.instance.currentUser?.uid)
.update({
'pets': FieldValue.arrayRemove(snap.data()!["pets"]!)
});
await FirebaseFirestore.instance
.collection("users")
.doc(FirebaseAuth.instance.currentUser?.uid)
.update({
'pets': FieldValue.arrayRemove(snap.data()!["pets"]!),
});
await FirebaseFirestore.instance
.collection("users")
.doc(FirebaseAuth.instance.currentUser?.uid)
.update({
'pets': FieldValue.arrayUnion(snap.data()!["pets"]!),
});
Navigator.pop(context);
setState(() {
isLoadingEdit = false;
editableText = false;
});
const snackBar = SnackBar(
content: Text("Your pet's details have been changed"),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
} else {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PetFiles(
petId: widget.details["id"],
),
),
);
}
},
child: isLoadingEdit
? Container(
height: 15.sp,
width: 15.sp,
child: CircularProgressIndicator(
color: Colors.white,
strokeWidth: 2.sp,
),
)
: Text(
editableText ? "Save Changes" : "Pet Health Records",
style:
TextStyle(color: Colors.white, fontSize: 0.03.sw),
),
),
),
],
),
SizedBox(
height: 0.01.sh,
),
],
);
}
}
You can check out their official docs for deleting collections here.
Or you can upgrade your project to blaze plan and use this extension which takes care of it for you.
Alternatively you can use NodeJS and FirebaseFunctions to do this task for you. Use this code snippet
async function deleteCollection(db, collectionPath, batchSize) {
const collectionRef = db.collection(collectionPath);
const query = collectionRef.orderBy('__name__').limit(batchSize);
return new Promise((resolve, reject) => {
deleteQueryBatch(db, query, resolve).catch(reject);
});
}
async function deleteQueryBatch(db, query, resolve) {
const snapshot = await query.get();
const batchSize = snapshot.size;
if (batchSize === 0) {
// When there are no documents left, we are done
resolve();
return;
}
// Delete documents in a batch
const batch = db.batch();
snapshot.docs.forEach((doc) => {
batch.delete(doc.ref);
});
await batch.commit();
// Recurse on the next process tick, to avoid
// exploding the stack.
process.nextTick(() => {
deleteQueryBatch(db, query, resolve);
});
}
index.js

Failed host lookup from rest.coinapi.io

I am trying to fetch network data from the coinAPI to get the exchange rate for 1btc to usd.. but after fetching the api and awaiting it in price screen so the ui will give the exchange rate... I get failed host lookup
This is the coin_data.dart file... contains the api and networking
import 'dart:convert';
import 'package:http/http.dart' as http;
const List<String> currenciesList = [
'AUD',
'BRL',
'CAD',
'CNY',
'EUR',
'GBP',
'HKD',
'IDR',
'ILS',
'INR',
'JPY',
'MXN',
'NOK',
'NZD',
'PLN',
'RON',
'RUB',
'SEK',
'SGD',
'USD',
'ZAR'
];
const List<String> cryptoList = [
'BTC',
'ETH',
'LTC',
];
const coinAPIUrl = 'https://rest.coinapi.io/v1/exchangerate';
const apiKey = 'APIKEY';
class CoinData {
Future<dynamic> getCoinData() async {
// http.Response response = await http.get(Uri.parse('$coinAPIUrl/BTC/USD?apikey=$apiKey'));
http.Response response = await http.get(Uri.parse('$coinAPIUrl/BTC/USD?apikey=$apiKey'));
if (response.statusCode == 200) {
var decodedData = jsonDecode(response.body);
var lastPrice = decodedData['rate'];
return lastPrice;
} else {
print(response.statusCode);
throw 'Problem with the get request';
}
}
}
This is the price_screen.dart file.. the actual UI and display of the exchange rate
import 'dart:io' show Platform;
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:ticker_bitcoin/coin_data.dart';
class PriceScreen extends StatefulWidget {
const PriceScreen({super.key});
#override
State<PriceScreen> createState() => _PriceScreenState();
}
class _PriceScreenState extends State<PriceScreen> {
late String selectedCurrency = 'USD';
DropdownButton<String> androidDropdown() {
List<DropdownMenuItem<String>> dropdownItems = [];
for (int i = 0; i < currenciesList.length; i++) {
String currency = currenciesList[i];
var newItem = DropdownMenuItem(
value: currency,
child: Text(currency),
);
dropdownItems.add(newItem);
}
return DropdownButton(
value: selectedCurrency,
items: dropdownItems,
onChanged: (value) {
setState(() {
selectedCurrency = value!;
});
},
);
}
CupertinoPicker iOSPicker() {
List<Text> pickerItems = [];
for (String currency in currenciesList) {
Text(currency);
pickerItems.add(Text(currency));
}
return CupertinoPicker(
itemExtent: 32.0,
onSelectedItemChanged: (selectedIndex) {
print(selectedIndex);
},
children: pickerItems,
);
}
// Widget getPicker() {
// if (Platform.isIOS) {
// return iOSPicker();
// } else if (Platform.isAndroid) {
// return androidDropdown();
// }
// return getPicker();
// }
String bitcoinValueInUSD = '?';
void getData() async {
try {
double data = await CoinData().getCoinData();
setState(() {
bitcoinValueInUSD = data.toStringAsFixed(0);
});
} catch (e) {
print(e);
}
}
#override
void initState() {
super.initState();
getData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('🤑 Coin Ticker'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(18.0, 18.0, 18.0, 0),
child: Card(
color: Colors.lightBlueAccent,
elevation: 5.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 15.0, horizontal: 28.0),
child: Text(
'1 BTC = $bitcoinValueInUSD USD',
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 20.0,
color: Colors.white,
),
),
),
),
),
Container(
height: 125.0,
alignment: Alignment.center,
padding: const EdgeInsets.only(bottom: 30.0),
color: Colors.lightBlue,
child: Platform.isIOS ? iOSPicker() : androidDropdown(),
),
],
),
);
}
}
It means your device/emulator got disconnected to the internet. If your host is connected to internet but emulator is disconnected then a cold reboot will do the trick. You'll find that under Device Manager > vertical ellipsis (⋮) > Cold Boot Now button.

State not triggering while clicking login button

Every thing is working fine except that the page is not navigating while I press login button. The user is logged in and The screen is changing once I reload it. But the screen has to change when I click the login button. I used the setState fuction But still not working.Please help me solve this. Thanks in advance.
This is my root page
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:login/main.dart';
import 'package:login/services/auth_service.dart';
class Root extends StatefulWidget {
const Root({Key? key}) : super(key: key);
#override
State<Root> createState() => _RootState();
}
enum AuthState { signedIn, signedOut }
class _RootState extends State<Root> {
AuthState _authState = AuthState.signedOut;
AuthService auth = AuthService();
String authuser = "ghnfgjy";
void signOut() async {
await auth.signOut();
setState(() {
_authState = AuthState.signedOut;
});
}
void signIn() async {
setState(() {
_authState = AuthState.signedIn;
});
}
#override
void initState() {
super.initState();
auth.currentUser().then((user) {
print("check check $user ");
setState(() {
_authState = user == null ? AuthState.signedOut : AuthState.signedIn;
});
});
}
#override
Widget build(BuildContext context) {
if (_authState == AuthState.signedOut) {
return Login();
} else {
return Scaffold(
body: Center(
child: Column(
children: [
SizedBox(
height: 69,
),
Text("Helllloooooooo $authuser"),
SizedBox(
height: 45,
),
FlatButton(
onPressed: () {
signOut();
},
child: Text("Sign out"))
],
),
));
}
}
}
This is my login.dart page
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:login/main.dart';
import 'package:login/services/auth_service.dart';
import 'package:login/share/constant.dart';
class Login extends StatefulWidget {
const Login({Key? key}) : super(key: key);
#override
_LoginState createState() => _LoginState();
}
enum FormType {
login,
register,
}
class _LoginState extends State<Login> {
dynamic _email;
dynamic _password;
final formkey = GlobalKey<FormState>();
FormType _formType = FormType.login;
dynamic result;
AuthService auth = AuthService();
bool validateandsave() {
final form = formkey.currentState;
if (form!.validate()) {
form.save();
print('form is valid');
print('$_email $_password');
return true;
} else {
print('form is not valid');
return false;
}
}
Future validateandsumit() async {
if (validateandsave()) {
if (_formType == FormType.register) {
auth.register(_email, _password);
setState(() {
_formType = FormType.login;
});
} else {
auth.signIn(_email, _password);
}
}
}
void moveToRegister() {
formkey.currentState!.reset();
setState(() {
_formType = FormType.register;
});
}
void moveToLogin() {
formkey.currentState!.reset();
setState(() {
_formType = FormType.login;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
decoration: BoxDecoration(
gradient: const LinearGradient(
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: [
Colors.blueAccent,
Colors.purple,
],
),
),
padding: EdgeInsets.all(16),
child: Form(
key: formkey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: openText() + inputFields() + buttons(),
),
),
),
);
}
List<Widget> openText() {
if (_formType == FormType.register) {
return [
Text(
'Please Register to continue',
style: TextStyle(
fontSize: 35, color: Colors.white, fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
SizedBox(
height: 40,
),
];
} else {
return [
Text('Please Login to continue',
style: TextStyle(
fontSize: 35, color: Colors.white, fontWeight: FontWeight.bold),
textAlign: TextAlign.center),
SizedBox(
height: 40,
),
];
}
}
List<Widget> inputFields() {
return [
TextFormField(
decoration: inputDecoration.copyWith(
labelText: 'Email Address',
),
style: TextStyle(color: Colors.black),
validator: (val) => val!.isEmpty ? 'Enter the email address' : null,
onSaved: (val) => _email = val),
SizedBox(
height: 20,
),
TextFormField(
obscureText: true,
decoration: inputDecoration.copyWith(
labelText: 'Password',
),
style: TextStyle(color: Colors.black),
validator: (val) => val!.isEmpty ? 'Enter the password' : null,
onSaved: (val) => _password = val),
SizedBox(
height: 60,
),
];
}
List<Widget> buttons() {
if (_formType == FormType.register) {
return [
FlatButton(
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 60),
onPressed: validateandsumit,
child: Text(
'Register',
style: TextStyle(fontSize: 20, color: Colors.white),
),
color: Colors.pinkAccent,
),
SizedBox(
height: 20,
),
FlatButton(
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 60),
onPressed: moveToLogin,
child: Text(
'Have an account? Login',
style: TextStyle(fontSize: 20, color: Colors.white),
),
color: Colors.pinkAccent,
),
];
} else {
return [
FlatButton(
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 60),
onPressed: validateandsumit,
child: Text(
'Login',
style: TextStyle(fontSize: 20, color: Colors.white),
),
color: Colors.pinkAccent,
),
SizedBox(
height: 20,
),
FlatButton(
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 60),
onPressed: moveToRegister,
child: Text(
'Register',
style: TextStyle(fontSize: 20, color: Colors.white),
),
color: Colors.pinkAccent,
),
];
}
}
}
This is my authservice file
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class AuthService {
FirebaseAuth _auth = FirebaseAuth.instance;
//Stream <User>? get authStateChanges => _auth.authStateChanges();
Stream<User?> get authStateChanges => _auth.authStateChanges();
CollectionReference users = FirebaseFirestore.instance.collection('users');
late User user;
//register in with email and password
Future register(email, password) async {
try {
UserCredential userCredential = await _auth
.createUserWithEmailAndPassword(email: email, password: password);
user = userCredential.user!;
print('Registered ${user.uid}');
var userdata = {
'email': email,
'password': password,
'role': 'user',
};
users.doc(user.uid).get().then((doc) {
if (doc.exists) {
doc.reference.update(userdata);
} else {
users.doc(user.uid).set(userdata);
}
});
} catch (e) {
print(e);
}
}
//sign in with email and password
Future signIn(email, password) async {
try {
UserCredential userCredential = await _auth.signInWithEmailAndPassword(
email: email, password: password);
user = userCredential.user!;
print('logged in ${user.uid}');
var userdata = {
'email': email,
'password': password,
'role': 'user',
};
users.doc(user.uid).get().then((doc) {
if (doc.exists) {
doc.reference.update(userdata);
} else {
users.doc(user.uid).set(userdata);
}
});
} catch (e) {
print(e);
}
}
Future currentUser() async {
try {
User user = await _auth.currentUser!;
return user.uid;
} catch (e) {
print(e);
}
}
//sign out
Future signOut() async {
try {
await _auth.signOut();
} catch (e) {
print(e);
}
}
}
I think the problem is that the build function in _RootState does not rebuild when you login.
One possible solution is to use StreamBuilder to rebuild whenever auth changes (login/logout).
Add this function to your AuthService class:
class AuthService {
final _auth = FirebaseAuth.instance;
...
Stream<User?> authStream() => _auth.authStateChanges(); // add this line
}
Then write your build function (in _RootState) as below:
#override
Widget build(BuildContext context) {
return StreamBuilder(
stream: auth.authStream(), // auth here is AuthService.
builder: (BuildContext context, AsyncSnapshot<User?> snapshot) {
// StreamBuilder will automatically rebuild anytime you log in or log
// logout. No need for your initState or signout & signin functions.
if (snapshot.hasError) return const Text('Something went wrong');
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
}
if (snapshot.data == null) return Login();
// snapshot.data is User.
// print(snapshot.data?.email); print(snapshot.data?.displayName);
return Scaffold(
body: Center(
child: Column(
children: [
const SizedBox(height: 69),
Text('Hello ${snapshot.data?.email}'),
const SizedBox(height: 45),
FlatButton(
onPressed: () async {
// no need to call sign out here.
await auth.signOut();
},
child: const Text('Sign out'),
)
],
),
),
);
},
);
// you can delete your initState, signin and signout functions in _RootState

Everything matches but I still get "Bad state: field does not exist within the DocumentSnapshotPlatform"

So i'm pretty lost trying to get my app to fetch not only the desired text from firestore but also the image i placed there. I know the error "Bad state: field does not exist within the DocumentSnapshotPlatform" implies that either I'm missing field or there's something wrong with at least one of those fields. There's only four things I'm trying to fetch from firestore "imgUrl, title, desc, organizer" i have checked for spelling and order and i can't figure it out. I have also checked firestore to see if the order and spelling was correct and i dont see what's the issue. Please help, Thank you so much in advanced.
////////////////////////////// News Class Starts\\\\\\\\\\\\\\
import 'package:myfuji/screens/CrudMethods.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'CrudMethods.dart';
import 'add_blog.dart';
class News extends StatefulWidget {
#override
_NewsState createState() => _NewsState();
}
class _NewsState extends State<News> {
CrudMethods crudMethods = CrudMethods();
late QuerySnapshot blogSnapshot;
#override
void initState() {
crudMethods.getData().then((result) {
blogSnapshot = result;
setState(() {});
});
super.initState();
}
Widget blogsList() {
return ListView.builder(
padding: const EdgeInsets.only(top: 24),
itemCount: blogSnapshot.docs.length,
itemBuilder: (context, index) {
return BlogTile(
organizer: blogSnapshot.docs[index].get('Organizer'),
desc: blogSnapshot.docs[index].get('desc'),
imgUrl: blogSnapshot.docs[index].get('imgUrl'),
title: blogSnapshot.docs[index].get('title'),
);
},
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Events"),
),
body: Container(
child: blogSnapshot != null
? blogsList()
: const Center(
child: CircularProgressIndicator(),
)),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => AddBlog()));
},
),
);
}
}
class BlogTile extends StatelessWidget {
final String imgUrl, title, desc, organizer;
const BlogTile(
{required this.organizer,
required this.desc,
required this.imgUrl,
required this.title});
#override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(bottom: 24, right: 16, left: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
child: ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(8)),
child: Image.network(
imgUrl,
width: MediaQuery.of(context).size.width,
fit: BoxFit.cover,
height: 200,
),
),
),
const SizedBox(height: 16),
Text(
title,
style: const TextStyle(fontSize: 17),
),
const SizedBox(height: 2),
Text(
'$desc - By $organizer',
style: const TextStyle(fontSize: 14),
)
],
),
);
}
}
///////////////////////////////////////////// class AddBlog begins here \\\\\\\\\\\
import 'dart:io';
import 'package:myfuji/screens/CrudMethods.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:random_string/random_string.dart';
class AddBlog extends StatefulWidget {
#override
_AddBlogState createState() => _AddBlogState();
}
class _AddBlogState extends State<AddBlog> {
//
late File selectedImage;
final picker = ImagePicker();
bool isLoading = false;
CrudMethods crudMethods = new CrudMethods();
Future getImage() async {
final pickedFile = await picker.getImage(source: ImageSource.gallery);
setState(() {
if (pickedFile != null) {
selectedImage = File(pickedFile.path);
} else {
print('No image selected.');
}
});
}
Future<void> uploadBlog() async {
if (selectedImage != null) {
// upload the image
setState(() {
isLoading = true;
});
Reference firebaseStorageRef = FirebaseStorage.instance
.ref()
.child("events/")
.child("${randomAlphaNumeric(9)}.jpg");
final UploadTask task = firebaseStorageRef.putFile(selectedImage);
var imageUrl;
await task.whenComplete(() async {
try {
imageUrl = await firebaseStorageRef.getDownloadURL();
} catch (onError) {
print("Error");
}
print(imageUrl);
});
// print(downloadUrl);
Map<String, dynamic> blogData = {
"imgUrl": imageUrl,
"Organizer": authorTextEditingController.text,
"title": titleTextEditingController.text,
"desc": descTextEditingController.text
};
crudMethods.addData(blogData).then((value) {
setState(() {
isLoading = false;
});
Navigator.pop(context);
});
// upload the blog info
}
}
//
TextEditingController titleTextEditingController =
new TextEditingController();
TextEditingController descTextEditingController = new TextEditingController();
TextEditingController authorTextEditingController =
new TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Create Blog"),
actions: [
GestureDetector(
onTap: () {
uploadBlog();
},
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 16),
child: Icon(Icons.file_upload)),
)
],
),
body: isLoading
? Container(
child: Center(
child: CircularProgressIndicator(),
))
: SingleChildScrollView(
child: Container(
margin: EdgeInsets.symmetric(horizontal: 16),
child: Column(
children: [
GestureDetector(
onTap: () {
getImage();
},
child: selectedImage != null
? Container(
height: 150,
margin: EdgeInsets.symmetric(vertical: 24),
width: MediaQuery.of(context).size.width,
child: ClipRRect(
borderRadius:
BorderRadius.all(Radius.circular(8)),
child: Image.file(
selectedImage,
fit: BoxFit.cover,
),
),
)
: Container(
height: 150,
decoration: BoxDecoration(
color: Colors.grey,
borderRadius:
BorderRadius.all(Radius.circular(8))),
margin: EdgeInsets.symmetric(vertical: 24),
width: MediaQuery.of(context).size.width,
child: Icon(
Icons.camera_alt,
color: Colors.white,
),
),
),
TextField(
controller: titleTextEditingController,
decoration: InputDecoration(hintText: "enter title"),
),
TextField(
controller: descTextEditingController,
decoration: InputDecoration(hintText: "enter desc"),
),
TextField(
controller: authorTextEditingController,
decoration:
InputDecoration(hintText: "enter author name"),
),
],
)),
),
);
}
}
///////////////////////////////////////////// class CrudMethods begins here \\\\\\\\\\\
import 'package:cloud_firestore/cloud_firestore.dart';
class CrudMethods {
Future<void> addData(blogData) async {
print(blogData);
FirebaseFirestore.instance
.collection("events/")
.add(blogData)
.then((value) => print(value))
.catchError((e) {
print(e);
});
}
getData() async {
return await FirebaseFirestore.instance.collection("events/").get();
}
}
/////////////////////////////////////////////firestore\\\\\\\\\\\\\
This maybe related to having “/“ after collection name here:
.collection("events/")
Instead try this:
.collection("events")
Also it may be best to change child to collection here:
Reference firebaseStorageRef = FirebaseStorage.instance
.ref()
.child("events/")
Try to see if you get data back by running this:
itemCount: blogSnapshot.docs.length,
itemBuilder: (context, index) {
QuerySnapshot snap = blogSnapshot.data; // Snapshot
List<DocumentSnapshot> items = snap.documents; // List of Documents
DocumentSnapshot item = items[index]; Specific Document
return BlogTile(
organizer: item.data['Organizer'],
desc: item.data['desc'],
imgUrl: item.data['imgUrl'],
title: item.data['title'],
);
},
I think you need to utilize a QueryDocumentSnapshot to access the data in the document.

Flutter : share a record

Im using record_mp3 package to record an audio file, can i share this record via whatsapp and other social media ?
Thanks in advance
You can copy paste run full code below
You can use package https://pub.dev/packages/esys_flutter_share
code snippet
onPressed: () async {
print('recordFilePath ${recordFilePath}');
File file = File(recordFilePath);
Uint8List bytes = await file.readAsBytes() as Uint8List;
await Share.file(
'yourmusic', 'yourmusic.mp3', bytes, 'audio/mpeg');
}
working demo
full code
import 'dart:io';
import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:record_mp3/record_mp3.dart';
import 'dart:io';
import 'dart:typed_data';
import 'package:esys_flutter_share/esys_flutter_share.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String statusText = "";
bool isComplete = false;
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Column(children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Expanded(
child: GestureDetector(
child: Container(
height: 48.0,
decoration: BoxDecoration(color: Colors.red.shade300),
child: Center(
child: Text(
'start',
style: TextStyle(color: Colors.white),
),
),
),
onTap: () async {
startRecord();
},
),
),
Expanded(
child: GestureDetector(
child: Container(
height: 48.0,
decoration: BoxDecoration(color: Colors.blue.shade300),
child: Center(
child: Text(
RecordMp3.instance.status == RecordStatus.PAUSE
? 'resume'
: 'pause',
style: TextStyle(color: Colors.white),
),
),
),
onTap: () {
pauseRecord();
},
),
),
Expanded(
child: GestureDetector(
child: Container(
height: 48.0,
decoration: BoxDecoration(color: Colors.green.shade300),
child: Center(
child: Text(
'stop',
style: TextStyle(color: Colors.white),
),
),
),
onTap: () {
stopRecord();
},
),
),
],
),
Padding(
padding: const EdgeInsets.only(top: 20.0),
child: Text(
statusText,
style: TextStyle(color: Colors.red, fontSize: 20),
),
),
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
play();
},
child: Container(
margin: EdgeInsets.only(top: 30),
alignment: AlignmentDirectional.center,
width: 100,
height: 50,
child: isComplete && recordFilePath != null
? Text(
"播放",
style: TextStyle(color: Colors.red, fontSize: 20),
)
: Container(),
),
),
]),
floatingActionButton: FloatingActionButton(
onPressed: () async {
print('recordFilePath ${recordFilePath}');
File file = File(recordFilePath);
Uint8List bytes = await file.readAsBytes() as Uint8List;
await Share.file(
'yourmusic', 'yourmusic.mp3', bytes, 'audio/mpeg');
},
child: Icon(Icons.share),
backgroundColor: Colors.green,
)),
);
}
Future<bool> checkPermission() async {
Map<PermissionGroup, PermissionStatus> map = await new PermissionHandler()
.requestPermissions(
[PermissionGroup.storage, PermissionGroup.microphone]);
print(map[PermissionGroup.microphone]);
return map[PermissionGroup.microphone] == PermissionStatus.granted;
}
void startRecord() async {
bool hasPermission = await checkPermission();
if (hasPermission) {
statusText = "正在录音中...";
recordFilePath = await getFilePath();
isComplete = false;
RecordMp3.instance.start(recordFilePath, (type) {
statusText = "录音失败--->$type";
setState(() {});
});
} else {
statusText = "没有录音权限";
}
setState(() {});
}
void pauseRecord() {
if (RecordMp3.instance.status == RecordStatus.PAUSE) {
bool s = RecordMp3.instance.resume();
if (s) {
statusText = "正在录音中...";
setState(() {});
}
} else {
bool s = RecordMp3.instance.pause();
if (s) {
statusText = "录音暂停中...";
setState(() {});
}
}
}
void stopRecord() {
bool s = RecordMp3.instance.stop();
if (s) {
statusText = "录音已完成";
isComplete = true;
setState(() {});
}
}
void resumeRecord() {
bool s = RecordMp3.instance.resume();
if (s) {
statusText = "正在录音中...";
setState(() {});
}
}
String recordFilePath;
void play() {
if (recordFilePath != null && File(recordFilePath).existsSync()) {
AudioPlayer audioPlayer = AudioPlayer();
audioPlayer.play(recordFilePath, isLocal: true);
}
}
int i = 0;
Future<String> getFilePath() async {
Directory storageDirectory = await getApplicationDocumentsDirectory();
String sdPath = storageDirectory.path + "/record";
var d = Directory(sdPath);
if (!d.existsSync()) {
d.createSync(recursive: true);
}
return sdPath + "/test_${i++}.mp3";
}
}