-
Notifications
You must be signed in to change notification settings - Fork 0
Firestorage integration #26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import 'package:firebase_storage/firebase_storage.dart'; | ||
|
||
class FirestorageEventPaused extends FirestorageEvent { | ||
const FirestorageEventPaused(super.event); | ||
} | ||
|
||
class FirestorageEventRunning extends FirestorageEvent { | ||
const FirestorageEventRunning(super.event); | ||
} | ||
|
||
class FirestorageEventSuccess extends FirestorageEvent { | ||
const FirestorageEventSuccess(super.event); | ||
Future<String> get downloadURL => _event.ref.getDownloadURL(); | ||
} | ||
|
||
class FirestorageEventCanceled extends FirestorageEvent { | ||
const FirestorageEventCanceled(super.event); | ||
} | ||
|
||
class FirestorageEventError extends FirestorageEvent { | ||
const FirestorageEventError(super.event); | ||
} | ||
|
||
sealed class FirestorageEvent { | ||
const FirestorageEvent(this._event); | ||
final TaskSnapshot _event; | ||
int get bytesTransferred => _event.bytesTransferred; | ||
int get totalBytes => _event.totalBytes; | ||
|
||
factory FirestorageEvent.fromSnapshot(TaskSnapshot event) => switch (event) { | ||
TaskSnapshot(state: TaskState.paused) => FirestorageEventPaused(event), | ||
TaskSnapshot(state: TaskState.running) => | ||
FirestorageEventRunning(event), | ||
TaskSnapshot(state: TaskState.success) => | ||
FirestorageEventSuccess(event), | ||
TaskSnapshot(state: TaskState.canceled) => | ||
FirestorageEventCanceled(event), | ||
TaskSnapshot(state: TaskState.error) => FirestorageEventError(event), | ||
}; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import 'dart:io'; | ||
|
||
import 'package:firebase_storage/firebase_storage.dart'; | ||
import 'package:instreal/features/posts/data/firestorage/firestorage_event.dart'; | ||
|
||
abstract interface class PostsFirestorage { | ||
Stream<FirestorageEvent> upload(File image); | ||
} | ||
|
||
class PostsFirestorageImpl implements PostsFirestorage { | ||
PostsFirestorageImpl({FirebaseStorage? storage}) | ||
: storageRef = (storage ?? FirebaseStorage.instance).ref("posts"); | ||
|
||
final Reference storageRef; | ||
|
||
@override | ||
Stream<FirestorageEvent> upload(File image) { | ||
final task = storageRef.child('image.jpg').putFile(image); | ||
return task.snapshotEvents.map<FirestorageEvent>( | ||
(event) => FirestorageEvent.fromSnapshot(event), | ||
); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,41 @@ | ||
import 'dart:io'; | ||
|
||
import 'package:flutter/material.dart'; | ||
|
||
@immutable | ||
class Post { | ||
class Post extends PostEntity { | ||
final String id; | ||
final String title; | ||
final String author; | ||
final String imageUrl; | ||
|
||
const Post({ | ||
required this.id, | ||
required this.title, | ||
required this.author, | ||
required super.title, | ||
required super.author, | ||
required this.imageUrl, | ||
}); | ||
} | ||
|
||
@immutable | ||
class PostDraft extends PostEntity { | ||
final File imageFile; | ||
|
||
const PostDraft({ | ||
required super.title, | ||
required super.author, | ||
required this.imageFile, | ||
}); | ||
|
||
Post toPost(String imageUrl) => Post( | ||
id: "", | ||
title: title, | ||
author: author, | ||
imageUrl: imageUrl, | ||
); | ||
} | ||
|
||
@immutable | ||
sealed class PostEntity { | ||
final String title; | ||
final String author; | ||
const PostEntity({required this.title, required this.author}); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,10 @@ | ||
import 'dart:io'; | ||
|
||
import 'package:flutter/material.dart'; | ||
import 'package:google_fonts/google_fonts.dart'; | ||
import 'package:instreal/features/posts/data/firestorage/posts_firestorage.dart'; | ||
import 'package:instreal/features/posts/post_entity.dart'; | ||
import 'package:instreal/features/posts/posts_firestore.dart'; | ||
import 'package:instreal/features/posts/data/firestore/posts_firestore.dart'; | ||
import 'package:instreal/features/posts/posts_repository.dart'; | ||
import 'package:instreal/l10n/index.dart'; | ||
import 'package:instreal/presentation/components/index.dart'; | ||
|
@@ -14,7 +17,10 @@ class MyHomePage extends StatefulWidget { | |
} | ||
|
||
class _MyHomePageState extends State<MyHomePage> { | ||
final postingsRepo = PostsRepositoryImpl(firestore: PostFirestoreImpl()); | ||
final postingsRepo = PostsRepositoryImpl( | ||
firestore: PostFirestoreImpl(), | ||
firestorage: PostsFirestorageImpl(), | ||
); | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
|
@@ -68,13 +74,13 @@ class _MyHomePageState extends State<MyHomePage> { | |
floatingActionButton: FloatingActionButton( | ||
onPressed: () async { | ||
await postingsRepo.add( | ||
const Post( | ||
id: "", | ||
PostDraft( | ||
title: 'title', | ||
author: 'author', | ||
imageUrl: | ||
'https://i1.wp.com/www.suitcasescholar.com/wp-content/uploads/2012/08/DSC_2583.jpg', | ||
), | ||
imageFile: File( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The code here doesn't work. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One more thing to consider. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I think we need to pass the bytes instead. |
||
'https://i1.wp.com/www.suitcasescholar.com/wp-content/uploads/2012/08/DSC_2583.jpg', | ||
), | ||
).toPost('imageUrl'), | ||
); | ||
setState(() {}); | ||
}, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
rules_version = '2'; | ||
|
||
// Craft rules based on data in your Firestore database | ||
// allow write: if firestore.get( | ||
// /databases/(default)/documents/users/$(request.auth.uid)).data.isAdmin; | ||
service firebase.storage { | ||
match /b/{bucket}/o { | ||
match /{allPaths=**} { | ||
allow read, write: if false; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be implemented properly. I'm thinking of creating a type for the argument that contains metadata + filepath or byte array of the file.
@aliyazdi75 @billyandco What do you guys think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I think keeping metadata is useful and byte array.