Flutter表单应用:signature插件签名上传Firebase Storage及查看功能实现求助
signature Plugin to Firebase Storage Got it, let's walk through how to save your signature to Firebase Storage and retrieve it for viewing. I'll break this down into actionable steps with modified code for your component.
Step 1: Set Up Firebase Dependencies
First, make sure you have the required Firebase packages in your pubspec.yaml:
dependencies: flutter: sdk: flutter signature: ^5.4.0 # Use the latest version available firebase_core: ^2.15.0 firebase_storage: ^11.2.0
Run flutter pub get after updating, and don't forget to initialize Firebase in your main app function:
void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); runApp(const MyApp()); }
Step 2: Modify Your Signature Component
Let's update your Sig widget to add upload functionality, handle sending the signature to Firebase, and include a section to view saved signatures. Here's the adjusted code:
import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:signature/signature.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_storage/firebase_storage.dart'; 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, ); String? _savedSignatureUrl; // Stores the download URL of the uploaded signature @override void initState() { super.initState(); _controller.addListener(() => print('Signature updated')); } // Upload signature to Firebase Storage Future<void> _uploadSignature(Uint8List signatureData) async { try { // Create a unique filename (use user ID + timestamp for better uniqueness) final String fileName = 'signatures/${DateTime.now().millisecondsSinceEpoch}.png'; final storageRef = FirebaseStorage.instance.ref().child(fileName); // Upload the PNG byte data final uploadTask = storageRef.putData(signatureData); final snapshot = await uploadTask.whenComplete(() {}); // Get and store the download URL final downloadUrl = await snapshot.ref.getDownloadURL(); setState(() { _savedSignatureUrl = downloadUrl; }); ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Signature uploaded successfully!')), ); } catch (e) { print('Upload error: $e'); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Upload failed: ${e.toString()}')), ); } } @override Widget build(BuildContext context) { return MaterialApp( home: Builder( builder: (BuildContext context) => Scaffold( appBar: AppBar(title: const Text('Signature Manager')), body: ListView( children: <Widget>[ Signature( controller: _controller, height: 300, backgroundColor: Colors.lightBlueAccent, ), // Control Buttons Container( decoration: const BoxDecoration(color: Colors.black), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[ // Preview & Upload IconButton( icon: const Icon(Icons.preview), 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(title: const Text('Preview Signature')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( color: Colors.grey[300], child: Image.memory(data), ), const SizedBox(height: 20), ElevatedButton( onPressed: () => _uploadSignature(data), child: const Text('Upload to Firebase'), ), ], ), ), ); }, ), ); } } }, ), // Clear Canvas IconButton( icon: const Icon(Icons.clear), color: Colors.blue, onPressed: () { setState(() => _controller.clear()); }, ), ], ), ), // Display Saved Signature if (_savedSignatureUrl != null) Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text('Saved Signature:', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), const SizedBox(height: 10), Container( color: Colors.grey[300], child: Image.network(_savedSignatureUrl!), ), ], ), ), ], ), ), ), ); } }
Key Changes Explained
- Upload Function: The
_uploadSignaturemethod takes the signature's PNG byte data, uploads it to Firebase Storage with a unique filename, then retrieves and stores the download URL. - Preview & Upload Flow: Added an upload button in the preview screen so users can confirm their signature before uploading.
- Saved Signature Display: Once uploaded, the signature is shown using the download URL from Firebase Storage.
- Error Handling: Added snackbar feedback for both successful and failed uploads, plus console logs for debugging.
Step 3: Retrieve Signatures Later
If you need to pull up a saved signature elsewhere in your app, use the download URL you stored (you can save this URL in Firestore linked to a user or form ID for easy access). To display it, just use:
Image.network(yourSavedDownloadUrl);
If you need to fetch a signature by its filename, use this helper function:
Future<String> getSignatureUrl(String fileName) async { final storageRef = FirebaseStorage.instance.ref().child('signatures/$fileName'); return await storageRef.getDownloadURL(); }
内容的提问来源于stack exchange,提问作者reliable

