Flutter signature upload to firebase storage - firebase

I'm creating a form app and I need to savethe signature in database. I don't know what to save this signature plugin from the pub.dev, can someone help me with this? I can't find something in google. I have this seperated code, I'm trying to save it to firebase storage.
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:signature/signature.dart';
/// example widget showing how to use signature widget
class Sig extends StatefulWidget {
#override
_SigState createState() => _SigState();
}
class _SigState extends State<Sig> {
final SignatureController _controller = SignatureController(
penStrokeWidth: 1,
penColor: Colors.red,
exportBackgroundColor: Colors.white,
);
#override
void initState() {
super.initState();
_controller.addListener(() => print('Value changed'));
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Builder(
builder: (BuildContext context) => Scaffold(
body: ListView(
children: <Widget>[
Signature(
controller: _controller,
height: 300,
backgroundColor: Colors.lightBlueAccent,
),
//OK AND CLEAR BUTTONS
Container(
decoration: const BoxDecoration(color: Colors.black),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
//SHOW EXPORTED IMAGE IN NEW ROUTE
IconButton(
icon: const Icon(Icons.check),
color: Colors.blue,
onPressed: () async {
if (_controller.isNotEmpty) {
final Uint8List data = await _controller.toPngBytes();
if (data != null) {
await Navigator.of(context).push(
MaterialPageRoute<void>(
builder: (BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Container(
color: Colors.grey[300],
child: Image.memory(data),
),
),
);
},
),
);
}
}
},
),
//CLEAR CANVAS
IconButton(
icon: const Icon(Icons.clear),
color: Colors.blue,
onPressed: () {
setState(() => _controller.clear());
},
),
],
),
),
],
),
),
),
);
}
}
I want to upload it in firebase storage and also view it from firebase storage but I don't know how to do it.

If the plugin that are you are using can export the data to coordinates point, maybe you can store the signature on the database without any problems. You can check this for a possible solution:
Changing colour of CustomPaint changes for all previous points
I see this on your code:
final Uint8List data = await _controller.toPngBytes();
So maybe you can check if this data can be exported as a coordinate points or maybe as a base64 image in order to save it on a database.
I hope this can be helpful.

Related

Firebase : Why appearing [clound_firestore/permission-denied] for my firestore

I know there is a lot of similar posts, but I still cannot find my own answer for my issue. Since I want to get the data from firebase without pressing the button and diretly can get the data from it, therefore I have used the StreamBuilder for my coding but I still get this error. Is this is my firestore database or realtime database permission get any wrong?
--Issue warning--
Below are my coding:
import 'dart:async';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:profile_staff/edit_profile_page.dart';
import 'package:profile_staff/profile_widget.dart';
import 'package:profile_staff/user.dart';
import 'package:profile_staff/user_preferences.dart';
class ProfilePage extends StatefulWidget {
const ProfilePage({Key? key}) : super(key: key);
#override
_ProfilePageState createState() => _ProfilePageState();
}
class _ProfilePageState extends State<ProfilePage> {
final Stream<QuerySnapshot> users =
FirebaseFirestore.instance.collection('users').snapshots();
TextEditingController _controller = TextEditingController();
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
final user = UserPreferences.myUser;
return Scaffold(
appBar: AppBar(
leading: new IconButton(
onPressed: () {}, icon: new Icon(Icons.arrow_back_ios_sharp)),
title: Center(
child: Text(
'My Profile',
style: TextStyle(color: Colors.white),
),
),
actions: [
IconButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => EditProfilePage()),
);
},
icon: new Icon(Icons.create_outlined))
],
backgroundColor: Colors.green,
shadowColor: Colors.white,
elevation: 3,
),
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Read Data',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600),
),
Container(
height: 250,
padding: const EdgeInsets.symmetric(vertical: 20),
child: StreamBuilder<QuerySnapshot>(
stream: users,
builder: (
BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot,
) {
// if (!snapshot.hasData) {
// return Text('error404');
// }
if (snapshot.connectionState == ConnectionState.waiting) {
return Text('Loading');
}
final data = snapshot.requireData;
return ListView.builder(
itemCount: data.size,
itemBuilder: (context, index) {
return Text(
'My name is ${data.docs[index]['name']} and I am ${data.docs[index]['age']}');
},
);
},
))
],
),
}
My Firestore Database:
My Realtime Database:
enter image description here
enter image description here
I was facing same issue.Forgot to deploy/upload new rules

Flutter/Firebase - Right Track?

At 54 I'm self-learning Flutter and have come a long way. I am stuck (again) with a speed-bump concerning my implementation of Firebase. Although I am getting the very basic of displaying a line of data for each record the problem is getting to the details of each record. I believe the issue is that I am not referencing the record ID.
When looking at endless examples I also believe my code to display a ListView of records is bloated making it more difficult to grab a record and display all fields (edit screen).
I want to click the "Walsh-Test" links to view all fields and update. I can create a new edit/update screen my initial problem is opening the screen to the selected record.
Any advice would be greatly appreciated.
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/rendering.dart';
class MeterReadHomeScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Color(0xff4367b1),
automaticallyImplyLeading: false,
leading: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Icon(
Icons.arrow_back,
color: Colors.white,
),
),
title: Text(
"WelakaOne",
style: TextStyle(
color: Colors.white,
),
),
),
body: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('meter_reads')
.orderBy('accountname')
.snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
return Padding(
padding: const EdgeInsets.fromLTRB(6, 20, 0, 0),
child: Container(
child: GestureDetector(
onTap: () {},
child: ListView(
children: snapshot.data.docs.map(
(document) {
return Row(
children: [
Container(
width: 50,
child: Icon(
Icons.access_alarm,
size: 36,
color: Color(0xff4367b1),
),
),
Container(
child: Text(
document['accountname'],
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Color(0xff4367b1),
),
),
),
SizedBox(height: 44),
],
);
},
).toList(),
),
),
),
);
},
),
);
}
}
[![Flutter/Firebase/Open to Selected Record][1]][1]
I understand that you want to go to another page (Edit Screen) onTapping the alarm tile.
So, my suggestion is to use A ListTile widget instead of the row widget you are using.
You can read about ListTile's onTap property, here
Regarding your routing to a new screen/page, you'll have to make use of MaterialPageRoute to create a new route and using Navigator's push method you can push it onto your Material App.
Attaching an example code that uses Navigator to go to different pages, you need the BuildContext of your app. Here is an example of how you can get it:
import 'package:flutter/material.dart';
import 'package:rate_your_professor/screens/firstScreen.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Some App',
home: SomeApp(),
);
}
}
class SomeApp extends StatelessWidget {
Widget getListView(BuildContext context) {
var listView = ListView(
children: <Widget>[
Text(
"XXXXXXXXXXXXXXX",
textDirection: TextDirection.rtl,
textAlign: TextAlign.center,
),
ListTile(
leading: Icon(Icons.location_city),
title: Text("XXXXX ", textDirection: TextDirection.rtl),
subtitle: Text(
"XXXXXXXXXX",
textDirection: TextDirection.rtl,
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => YourNewPage(),
),
);
},
),
],
);
return listView;
}
#override
Widget build(BuildContext context) {
return Scaffold(body: getListView(context));
}
}

Add image from gallery to user document id using Flutter and Firebase

I am developing an app, and I want to create a user profile for each logged-in user. With my code now, I am able to get the user information from the cloud Firestore of each user uid document, but I want the user to be able to add an image to firebase storage, and then get this image, add to the specific user uid doc, and display on the app. Basically, I know how to get the data I have already, I just don't know how to update the user doc, especially with images.
Here is the code I have for the user profile:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:tradie_app/scr/providers/authService.dart';
import 'package:tradie_app/scr/screens/edit_company_email.dart';
import 'package:tradie_app/scr/widgets/loading.dart';
import 'home.dart';
class CompanyProfile extends StatefulWidget {
#override
_CompanyProfileState createState() => _CompanyProfileState();
}
class _CompanyProfileState extends State<CompanyProfile> {
// Keep track of the form for validation
final _formKey = GlobalKey<FormState>();
// Loading Icon
bool loading = false;
final AuthService _authService = AuthService();
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
final FirebaseFirestore _firebaseFirestore = FirebaseFirestore.instance;
Future getCompanyNameData() async {
final CollectionReference users =
_firebaseFirestore.collection("Companies");
final String uid = _firebaseAuth.currentUser.uid;
final result = await users.doc(uid).get();
return result.data()["companyName"];
}
Future getCompanyEmailData() async {
final CollectionReference users =
_firebaseFirestore.collection("Companies");
final String uid = _firebaseAuth.currentUser.uid;
final result = await users.doc(uid).get();
return result.data()["companyEmail"];
}
#override
Widget build(BuildContext context) {
return loading
? Loading()
: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
iconTheme: IconThemeData(color: Colors.black),
backgroundColor: Colors.white,
title: Text(
"Create the company profile",
style: TextStyle(
color: Colors.black,
),
),
elevation: 0.0,
),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
UserAccountsDrawerHeader(
accountName: FutureBuilder(
future: getCompanyNameData(),
builder: (_, AsyncSnapshot snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Text("Loading");
}
return Text(snapshot.data);
},
),
),
ListTile(
leading: Icon(Icons.logout),
title: Text(
"Log Out",
),
onTap: () async {
await _authService.signOut();
},
),
],
),
),
body: Padding(
padding: const EdgeInsets.all(18.0),
child: SingleChildScrollView(
child: Container(
child: Form(
key: _formKey,
child: Column(
children: [
Row(
children: [
Text(
"Company name: ",
style: TextStyle(
color: Colors.black,
fontSize: 20.0,
),
),
],
),
SizedBox(
height: 10.0,
),
Row(
children: [
FutureBuilder(
future: getCompanyNameData(),
builder: (_, AsyncSnapshot snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Text("Loading");
}
return Text(
snapshot.data,
style: TextStyle(
color: Colors.black, fontSize: 15.0),
);
},
),
],
),
SizedBox(
height: 20.0,
),
Row(
children: [
Text(
"Company email: ",
style: TextStyle(
color: Colors.black,
fontSize: 20.0,
),
),
],
),
SizedBox(
height: 10.0,
),
Row(
children: [
FutureBuilder(
future: getCompanyEmailData(),
builder: (_, AsyncSnapshot snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Text("Loading");
}
return Text(
snapshot.data,
style: TextStyle(
color: Colors.black,
fontSize: 15.0,
),
);
},
),
IconButton(
icon: Icon(Icons.edit),
onPressed: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
EditCompanyEmailScreen(),
),
),
),
],
),
SizedBox(
height: 20.0,
),
Row(
children: [
Text(
"Company phone number: ",
style: TextStyle(
color: Colors.black,
fontSize: 20.0,
),
),
],
),
SizedBox(
height: 20.0,
),
// Here is where I want to add the image
Row(
children: <Widget>[],
),
],
),
),
),
),
),
);
}
}
To select the image from gallery add this plugin. And then call this function to select the image.
File _image;
selectImageFromGallery() async
{
final picker=ImagePicker();
setState(() {
inProcess=true;
});
final imageFile= await picker.getImage(source: ImageSource.gallery);
if(imageFile!=null)
{
_image=File(imageFile.path);
}
setState(() {
inProcess=false;
});
}
after selecting the image run this function to store image to firebase and get url of the image.
Future<String> uploadFile(File image) async
{
String downloadURL;
String postId=DateTime.now().millisecondsSinceEpoch.toString();
Reference ref = FirebaseStorage.instance.ref().child("images").child("post_$postId.jpg");
await ref.putFile(image);
downloadURL = await ref.getDownloadURL();
return downloadURL;
}
now lets upload and update data in firestore docs and storage.
uploadToFirebase()async
{
String url=await uploadFile(_image); // this will upload the file and store url in the variable 'url'
await users.doc(uid).update({ //use update to update the doc fields.
'url':url
});
}
To show the selected image add this in your Ui:-
Container(
height: 200,
width: 200,
decoration: BoxDecoration(image: DecorationImage(image: FileImage(_image,),fit: BoxFit.contain)),
)
After adding this image make a button for upload:-
RaisedButton()
{
onPressed:(){
uploadToFirebase();
},
child:Text("Upload"),
}
After selecting the image user will click on this button to upload and save sata to firebase.
You need to upload the image chosen from gallery to your firebase storage and then use the url in your firestore.
here is a samle code to upload the image to storage
import 'package:firebase_storage/firebase_storage.dart' as firebase_storage;
final ref = firebase_storage.FirebaseStorage.instance.ref().child("profile-pic/abc.jpg");
final imageFile = await ImagePicker.pickImage(source: ImageSource.gallery);
final uploadTask = ref.putFile(imageFile);
final snapshot = await uploadTask.whenComplete(() => null);
imageUrl = await snapshot.ref.getDownloadURL();
use the imageUrl and update it in your firestore collection for the user.
You can fetch the url and display image whenever you need.

Use Firestore to access images stored locally in a Flutter Project

I have Images of flags stored locally within my Flutter project assets/images folder i stored name of the images in firestore by opening a collection called "Languages" then set fields two fields
Languages [Collection] with auto id documents
1. Language_Image -> china.png [Fields]
2. Language_Name -> Chinese [Fields]
I want to generate a GridView of the flags (CircleAvatar) of every language and name of the language (Text)
I don't know how to go about the process to iterate through each document and get Language_Image and Language_Name data and build my GridView here is my code
`
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'Choose_Books.dart';
class ChooseLanguage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey.shade300,
appBar: AppBar(
automaticallyImplyLeading: false,
title: Text("Choose ChooseLanguage To Learn",
style: TextStyle(fontSize: ScreenUtil().setHeight(34)),
),
centerTitle: false,
),
body: ChooseLanguageBody(),
);
}
}
class ChooseLanguageBody extends StatefulWidget {
#override
_ChooseLanguageBodyState createState() => _ChooseLanguageBodyState();
}
class _ChooseLanguageBodyState extends State<ChooseLanguageBody> {
#override
Widget build(BuildContext context) {
return StreamBuilder(
stream: Firestore.instance.collection('Language').snapshots(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (!snapshot.hasData) {
return Center(
child: const Text('Loading events...'));
}return GridView.count(
// Create a grid with 3 columns.
crossAxisCount: 2,
children: List.generate(24, (index) {
return Center(
child: CupertinoButton(
child: Column(
children: <Widget>[
CircleAvatar(
maxRadius: 70.0,
backgroundImage: AssetImage('images/launguages/launguage${snapshot.data.documents[index]['Language_Image']}.png'),
),
Text(snapshot.data.documents[index]['Language_Image'], style: TextStyle(fontSize: ScreenUtil().setHeight(24), fontWeight: FontWeight.bold),
)
],
),
onPressed: () {Navigator.push(context, MaterialPageRoute(builder: (context) => ChooseBook()));},
),
);
}),
);
}
);
}
}
`
Is it the correct procedure am following or i messed up completely?
I think I found the Problem.
You missed adding the .data part.
Try this
snapshot.data.documents[index].data['Language_Image']
Hope this helps.!
(FYI-> your gig is lead to this problem)

Flutter: Firebase storage download url

I am new to Flutter and I am trying to make a wallpaper app where I use Firebase to store my images. The app retrieves images from Firebase and the user can share and download the images to the device. I'm using image_gallery_saver package but I wasn't able to get the url of the images so I can add it to the image_gallery_saver function, is there a simple way to get the url of an image from firebase after the user clicks on a specific image?
The following is the home page:
import 'package:cardstest2/Screens/ImageScreen.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'dart:async';
class FirestoreListViewPage extends StatefulWidget {
#override
_FirestoreListViewPageState createState() => _FirestoreListViewPageState();
}
class _FirestoreListViewPageState extends State<FirestoreListViewPage> {
Future _data;
Future getPosts() async {
var firestore = Firestore.instance;
QuerySnapshot qn = await firestore.collection("gallery").getDocuments();
return qn.documents;
}
#override
void initState() {
super.initState();
_data = getPosts();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: Text('Subcategories'),
),
body: Container(
child: FutureBuilder(
future: _data,
builder: (_, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: Text('Waiting...'),
);
} else {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (_, index){
return Card(
child: ListTile(
title: Image.network(snapshot.data[index].data['GalleryUrl']),
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => imageScreenPage(snapshot.data[index].data['GalleryUrl']),
),
);
},
),
);
});
}
}),
),
);
}
}
The following is the imageScreen page:
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:share/share.dart';
import 'package:dio/dio.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'dart:ui';
class imageScreenPage extends StatefulWidget {
String cardPath;
imageScreenPage(this.cardPath);
#override
_imageScreenPageState createState() => _imageScreenPageState();
}
class _imageScreenPageState extends State<imageScreenPage> {
final LinearGradient backgroundGradient = new LinearGradient(
colors: [new Color(0x10000000), new Color(0x30000000)],
begin: Alignment.topLeft,
end: Alignment.bottomRight);
#override
Widget build(BuildContext context) {
return new Scaffold(
body: new SizedBox.expand(
child: new Container(
decoration: new BoxDecoration(gradient: backgroundGradient),
child: new Stack(
children: <Widget>[
new Align(
alignment: Alignment.center,
child: new Hero(
tag: widget.cardPath,
child: new Image.network(widget.cardPath),
),
),
new Align(
alignment: Alignment.topCenter,
child: new Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new AppBar(
elevation: 0.0,
backgroundColor: Colors.transparent,
leading: new IconButton(
icon: new Icon(
Icons.close,
color: Colors.black,
),
onPressed: () => Navigator.of(context).pop()),
)
],
),
),
],
),
),
),
persistentFooterButtons: <Widget>[
IconButton(
icon: Icon(Icons.wallpaper), onPressed: () {},
),
IconButton(
icon: Icon(Icons.file_download), onPressed: () {_save();},
),
IconButton(
icon: Icon(Icons.share), onPressed: () {Share.share(widget.cardPath);},
),
],
);
}
_save() async {
var response = await Dio().get("<insert url>", options: Options(responseType: ResponseType.bytes));
final result = await ImageGallerySaver.saveImage(Uint8List.fromList(response.data));
print(result);
}
}
To get the downloadUrl, then do the following:
StorageTaskSnapshot snapshot = await storage
.ref()
.child("images/$imageName")
.putFile(file)
.onComplete;
if (snapshot.error == null) {
final String downloadUrl =
await snapshot.ref.getDownloadURL();
}
use putFile to add the file to Firebase Storage, then you can use snapshot.ref.getDownloadURL() to get the url.
For all the people using flutter in 2021
This worked for me
import 'package:firebase_storage/firebase_storage.dart' as firebase_storage;
Future<String> uploadImage(imageFile) async {
firebase_storage.Reference ref = storage.ref().child('post_$postId.jpg');
firebase_storage.UploadTask uploadTask = ref.putFile(imageFile);
print('File Uploaded');
var imageUrl = await (await uploadTask).ref.getDownloadURL();
String url = imageUrl.toString();
return url;
}
uploadImage() is a function which takes in an imageFile
You have to call it using await uploadImage(imageFile) inside an asynchronous function

Resources