transform from Firestore API to firebase rtdb api - flutter

recently im learning to create a event from a tutorial, but the original one is made in firestore, and Im trying to use firebase rtdb,
here is original code:
class FirebaseApi {
static Future<String> createTodo(Todo todo) async {
final docTodo = FirebaseFirestore.instance.collection('todo').doc();
todo.id = docTodo.id;
await docTodo.set(todo.toJson());
return docTodo.id;
}
}
here is code I created, sorry my basic knowledge is now good, Idk what should i return
class FirebaseApi {
static Future<String> createTodo(Todo todo) async{
final todoRefMessages = FirebaseDatabase.instance.ref().child('todo');
final newTodo = FirebaseDatabase.instance.ref().child('todo').get().then((snapshot) async{
final json = Map<dynamic, dynamic>.from(snapshot.value);
final newTodo = Todo(
createdTime: Utils.toDateTime(json['createdTime']),
title: json['title'],
description: json['description'],
id: json['id'],
isDone: json['isDone'],
);
await todoRefMessages.set(newTodo.toJson());
return newTodo;
});
todo.id= newTodo.id;//here got error, The getter 'id' isn't defined for the type 'Future<Todo>
return newTodo.id;
}
}
could you please let me know how to create same method but for firebase rtdb, thanks in advance!

This call to Firestore give you a reference to a new non-existing document in the todo collection:
final docTodo = FirebaseFirestore.instance.collection('todo').doc();
Is equivalent to this in the Realtime Database is:
final todoRef = FirebaseDatabase.instance.ref("todo").push();
Then to store the JSON to that document in Firestore you do:
await docTodo.set(todo.toJson());
The equivalent in the Realtime Database is:
await todoRef.set(todo.toJson());
If you have errors in other parts of your code, I recommend keeping the functionality of your createTodo method exactly the same between the Firestore and Realtime Database implementations.
For example, I assume that the Todo todo object is exactly the same between the implementations. If it isn't, the problem is less likely to be in the database API calls, but probably in the implementation of Todo.

Related

Why can't my Firebase Cloud Firestore Collection update (.update) when I have already created one (.set)?

'I have a Firebase Cloud Firestore Collection. When I am trying to update it, it can't find it. I can however see the newly created file in my collection. Anyone who knows how to fix this? I am fairly new in coding. Thank you in advance.
This the part of the code where we get the error, it is also mentioned elsewhere:'
class DatabaseService {
final String? uid;
DatabaseService({this.uid});
//collection reference
final CollectionReference listenCollection =
FirebaseFirestore.instance.collection('listen');
Future updateUserData(String status, String name, int score) async {
return await listenCollection.doc(uid).set({
'status': status,
'name': name,
'score': score,
});
}
Future updateName(String name) async {
return await listenCollection.doc(uid).update({'name': name});
}
Stream<QuerySnapshot> get listen {
return listenCollection.snapshots();
}
}

What is the best way to work with files in Flutter?

I'm a junior working with flutter and hit a problem.
I need to open a file, read and compare some data everytime the app opens and then change some of that data as the app progress. We tried using .txt files to read and write some text, but when we had to look for something in the file was too complicated to change it and the file is not accessibe only on the device running the app. We also thought of using xml files but I don't know if is a good idea.
What would be a pratical solution for this situation, as the file needs to be opened all the time. Thanks.
Let's say our JSON looks like this:
{
title: 'some text',
values: [1,5,2,4,1,3],
}
And we want to make a UI that allows us to add values and to edit the title. First let's write a method to write and read from the JSON file:
Future<void> _write(Map<String, dynamic> value) async {
File f = File(_fileLocation);
String jsonStr = jsonEncode(value);
await f.writeAsString(jsonStr);
}
Future<Map<String, dynamic>> _read() async {
File f = File(_fileLocation); // maybe move this into a getter
final jsonStr = await f.readAsString();
return jsonDecode(jsonStr) as Map<String, dynamic>;
}
This way, the rest of the app should be trivial, but let's add a method to update the title and a method to add a new number:
Future<void> _updateTitle(String title) async {
var values = await _read();
values['title'] = title;
await _write(values);
}
Future<void> _addNumber(int number) async {
var values = await _read();
values['values'].push(number);
await _write(values);
}
Types with JSON and Dart can be a bit weird, so it is possible you need to use the as keyword when reading from the list:
Future<void> _addNumber(int number) async {
var values = await _read();
var valueList = (values['values'] as List<int>);
valueList.push(number);
values['values'] = valueList;
await _write(values);
}
Hopefully, this example helps

Flutter - How to add and retrieve data to/from hive?

I know it sounds simple and I went through the example given in the documentation. Yet somehow I am unable to get it right.
This is what I have:
void main() async {
await Hive.initFlutter();
//Hive.openBox('workoutBox');
runApp(const MyApp());
}
...
Next Screen:
var box;
...
Trying to add to the box
Future<void> _save() async{
// save doc id somewhere
final Id = doc.id;
//box = await Hive.openBox('workoutBox');
box.put("Id", Id);
}
Trying to retrieve in another function:
var someId = box.get("Id");
Current error: get was called on null
My confusion is, where/how do you declare, open and retrieve from the box in this situation?
It seems you are forgetting to initialize a Box param and assign the value returned by the openBox function to it.
After Hive initialization you should have something like this:
Box<myValue> boxValue = await Hive.openBox("myKey");
Important: the retrieval method will dependend based on what you need to do and, more importantly, how you saved your data in the first place.
Let's say you saved data like this:
await boxValue.add(value);
By adding data like this, the key assigned to the value will be an auto-incremented one, so that trying to retrieve it with a specific key that never was assigned in the first place will fail.
If you did add the data like this:
await boxValue.put("myKey", value);
then you will be able to successfully fetch it using the intended key.
You can do the following:
void main() async {
await Hive.initFlutter();
await Hive.openBox('workoutBox'); //<- make sure you await this
runApp(const MyApp());
}
...
_save() { // <- can be a synchronous function
final box = Hive.box('workoutBox'); //<- get an already opened box, no await necessary here
// save doc id somewhere
final Id = doc.id;
box.put("Id", Id);
}
I have written an example app and a Flutter Cubits + Hooks + Hive DB tutorial. I have the following AppDatabase class there:
const String _bookBox = 'book';
#Singleton()
class AppDatabase {
AppDatabase._constructor();
static final AppDatabase _instance = AppDatabase._constructor();
factory AppDatabase() => _instance;
late Box<BookDb> _booksBox;
Future<void> initialize() async {
await Hive.initFlutter();
Hive.registerAdapter<BookDb>(BookDbAdapter());
_booksBox = await Hive.openBox<BookDb>(_bookBox);
}
Future<void> saveBook(Book book) async {
await _booksBox.put(
book.id,
BookDb(
book.id,
book.title,
book.author,
book.publicationDate,
book.about,
book.readAlready,
));
}
Future<void> deleteBook(int id) async {
await _booksBox.delete(id);
}
...

Get data from firestore and convert to json and use that in factory constructor

I am using a firestore as database. If the data not present in database then it will do webscrape. In webscrape I managed to convert the data into json and used factory constructor. I want the same thing should happen while fetching data from firestore.
One More thing I have a specific collection and document id So I used .collection('medicine').doc('id').get().
Factory Constructor
class Tablet {
String name;
String introduction;
Tablet({
this.name,
this.introduction,
});
factory Tablet.fromJson(Map<String, dynamic> json) {
return Tablet(
name: json['name'],
introduction: json['introduction'],
);
}
}
Method which get Data from Database If Data Present
This is a Method which must returns Future<Tablet> (I stuck in if condition)
Future<Tablet> details;
Future<Tablet> getDetails(String medName) async {
await Firebase.initializeApp();
await FirebaseFirestore.instance
.collection('medicine')
.doc(medName.toLowerCase())
.get()
.then((DocumentSnapshot docSnapshot) {
if (docSnapshot.exists) {
var json = jsonDecode(docSnapshot.data().toString()); // I am getting stuck here
details = Tablet.fromJson(json) as Future<Tablet>;
} else {
print('Data not present in Database..');
details = webScrape(medName);
}
});
return details;
}
What I Tried in webscrape(medName) is
Tablet.fromJson(jsonDecode(response.body));
Here returning above line and assigning it to Future works but in the if condition, It is asking for type cast and the following error thrown
Error
FormatException: Unexpected character (at character 2)
{benefits: {values: [{header: In Heartburn, display_text: Heartburn and aci...
^
Update
As #Tarik Huber 2nd suggestion, Inspired and changed a code little bit as shown
factory Tablet.fromSnapshot(DocumentSnapshot docSnap){
return Tablet(
name: docSnap.get('name');
introduction: docSnap.get('introduction');
);
}
Now My Question is, the below code isn't working
details = Tablet.fromSnapshot(docSnapshot.data()) as Future<Tablet> // is not working
instead calling async function did as shown
details = arrangeData(docSnapshot.data());
Future<Tablet> arrangeData(DocumentSnapshot data) async{
return Tablet.fromSnapshot(data);
}
I know It's not a good approach and It is working but don't know How? Can anyone Explain..
Have you tried it with:
details = Tablet.fromJson(docSnapshot.data()) as Tablet;
the data is of type Map<String,dynamic>. That is the same type your convertion functions takes.
Othervise you could just add a
factory Tablet.fromSnapshot(DocumentSnapshot docSnapshot) {
return Tablet(
name: docSnapshot.get('name'),
introduction: docSnapshot.get('introduction'),
);
}

How to use a String returned by a Future<String> method in flutter?

I'm trying to read a json file's components using the following method:
import 'dart:io';
class CharacterDataReader {
Future<String> read() async {
final file = File('assets/data/character_data.json');
String data = await file.readAsString();
return data;
}
}
Now, I'm trying to assign the read values to a String named data and json.decode() it in another class using the following:
Future<String> data = CharacterDataReader().read();
Map<String, dynamic> characterData = json.decode(data);
However, this doesn't work since json.decode() only accepts Strings as a parameter. Therefore, can someone please tell me how do I convert this Future into an actual string?
since its a future you have to add await keyword
String data= await CharacterDataReader().read();
check out dart official doc on asynchronous programming