This is my code for add new address in firebase realtime database
Future<bool> addAddress(Address adr)async{
database = FirebaseDatabase(app: app);
await database
.reference()
.child(table_name).child(uid)
.set(adr).then((onValue){
print("adress add complected");
return true;
}).catchError((onError){
print("adress add failed $uid");
print(onError);
return false;
});
}
but it returning error
Invalid argument: Instance of 'Address'
Where is i am doging wrong ?
Your input for set() has to be type Map, so you have to do something like this:
Future<bool> addAddress(Address adr)async{
database = FirebaseDatabase(app: app);
await database
.reference()
.child(table_name).child(uid)
.set({
"country": adr.count,
"state": adr.state,
"city": adr.city,
}).then((onValue){
print("adress add complected");
return true;
}).catchError((onError){
print("adress add failed $uid");
print(onError);
return false;
});
}
Related
I want to display the current user name on my app.
I tried this but got the error
Unhandled Exception: Bad state: cannot get a field on a DocumentSnapshotPlatform which does not exist
Future getUserData() async {
User? user = await FirebaseAuth.instance.currentUser;
final DocumentSnapshot doc = await FirebaseFirestore.instance
.collection("UserData")
.doc(user!.uid)
.get();
name = doc['name'];
print("name $name");
}
Then, I tried this:
Future getUserData() async {
User? user = await FirebaseAuth.instance.currentUser;
try {
final doc = await FirebaseFirestore.instance
.collection("UserData")
.doc(user!.uid)
.get();
final ds = await doc.get();
final data = ds.data() as Map<String, dynamic>;
name = data['name'];
print("name $name");
} catch (e) {
print(e.toString());
return null;
}
}
But it shows an error for the doc.get()
1 positional argument(s) expected, but 0 found.
Try adding the missing arguments
What can I do?
.get method expect a key('String') of filed/filePath.
final doc = await FirebaseFirestore.instance
.collection("UserData")
.doc(user!.uid)
.get();
final name = await doc.get("name");
print("name $name");
Also make sure the project setup is ok. More about reading data.
I try to make transaction to insert data in database using sqflite
i can't put this transaction into function for null safety problem for i can't know the
return type of this function
Future insertDataBase() async{
return await dataBase?.transaction(
(txn) {
txn.rawInsert('').then((value)
{
print('data added');
}
).catchError
(
(error){
print('error row : ${error.toString()}');
});
}
);
}```
I am working on a Flutter app and I am testing on both Android and iOS devices. My app works perfectly on a physical Android device and it works on an iOS device with iOS 13. The problem is that since I updated the iOS device to iOS 14.3, I cannot insert into the database with SQFlite.
What does work
Android devices
iOS devices with iOS older than 14
Reading from the database (meaning items that were inserted into the database when the phone was on iOS 13 can successfully be retrieved after updating to iOS 14.3)
What does not work
Inserting into the database on iOS 14.3.
await db.transaction((txn) async {
return await txn.insert(TodoList.TABLENAME, TodoList.toMap(todoList),
conflictAlgorithm: ConflictAlgorithm.replace);
});
The app does not provide any error logs and it also does not crash; I can continue to interact with the app. It behaves as if it just disregards the database insert. I've tried a few different things to get it to work but I am at a loss. I appreciate any advice!
This is the first thing I tried: Flutter sqflite app does not working on real ios device
I also tried a workaround mentioned here (although it may not be relevant to my issue): Modify schema structure fails on iOS 14
Relevant Code
Dependencies (Edit: Issue occurs on any SQFlite version, even 1.3.2+2):
sqflite: ^1.3.0
path_provider: ^0.4.1
Database Class:
import 'dart:io';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:todo_list/data/todo_list.dart';
class DatabaseHelper {
//Create a private constructor
DatabaseHelper._();
static const databaseName = 'todos_database.db';
static final DatabaseHelper instance = DatabaseHelper._();
static Database _database;
Future<Database> get database async {
if (_database == null) {
return await initializeDatabase();
}
return _database;
}
initializeDatabase() async {
return await openDatabase(join(await getDatabasesPath(), databaseName),
version: 1, onCreate: (Database db, int version) async {
// Possible fix for iOS issue (did not work)
if (Platform.isIOS) {
await db.execute('PRAGMA sqflite -- db_config_defensive_off');
}
await db.execute(
"CREATE TABLE todos(id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, listName TEXT, items TEXT, completed TEXT, count INTEGER, color INTEGER, ordering INTEGER)");
});
}
Future<List<TodoList>> retrieveTodos() async {
final Database db = await database;
final List<Map<String, dynamic>> maps = await db.query(TodoList.TABLENAME);
return List.generate(maps.length, (i) {
return TodoList(
id: maps[i]["id"],
listName: maps[i]["listName"],
items: maps[i]["items"],
completed: maps[i]["completed"],
count: maps[i]["count"],
color: maps[i]["color"],
ordering: maps[i]["ordering"],
);
});
}
insertTodo(TodoList todoList) async {
final db = await database;
await db.transaction((txn) async {
return await txn.insert(TodoList.TABLENAME, TodoList.toMap(todoList),
conflictAlgorithm: ConflictAlgorithm.replace);
});
//return res;
}
updateTodo(TodoList todoList) async {
final db = await database;
await db.update(TodoList.TABLENAME, TodoList.toMap(todoList),
where: "id = ?",
whereArgs: [todoList.id],
conflictAlgorithm: ConflictAlgorithm.replace);
}
deleteTodo(int id) async {
var db = await database;
db.delete(TodoList.TABLENAME, where: "id = ?", whereArgs: [id]);
}
}
Call to insertToDo:
await DatabaseHelper.instance.insertTodo(TodoList(
listName: listName,
items: encodedTodo,
completed: encodedDone,
count: 0,
color: _mainColor.value,
ordering: order));
UPDATE
Attempted raw SQL query. No change, works fine on Android but not on iOS 14.3.
Insert function with raw query:
insertTodo(TodoList todoList) async {
final db = await database;
await db.transaction((txn) async {
return await txn.rawInsert(
'INSERT INTO todos(listName, items, completed, count, color, ordering) VALUES(?, ?, ?, ?, ?, ?)',
[
todoList.listName,
todoList.items,
todoList.completed,
todoList.count,
todoList.color,
todoList.ordering
]);
/*await txn.insert(TodoList.TABLENAME, TodoList.toMap(todoList),
conflictAlgorithm: ConflictAlgorithm.replace);*/
});
//return res;
}
Note, I've also tried insert without transaction.
insertTodo(TodoList todoList) async {
final db = await database;
return await db.insert(TodoList.TABLENAME, TodoList.toMap(todoList),
conflictAlgorithm: ConflictAlgorithm.replace);
}
In my Flutter Web application I am retrieving values from the map timeslots in Firestore.
This is what the data looks like:
But, instead of retrieving the whole list of values, I get a truncated list like this:
[Mo-Washing-(09:00-10:00, 10:00-11:00, 11:00-12:00, ..., 20:00-21:00, 21:00-22:00)]
Below I have included the 2 functions responsible for retrieving the data and adding it to the list object
static List object = [];
static Map<String, dynamic> timeDetails = {};
static Map<String, dynamic> userDetails = {};
checkExists(docuID) async {
return await firestore()
.collection('environments')
.doc(docuID)
.get()
.then((val) {
userDetails.addAll(val.data());
}).whenComplete(() async {
fs.DocumentSnapshot snapShot = await firestore()
.collection('environments')
.doc(docuID)
.collection('Washing')
.doc('monday')
.get();
if (snapShot == null || !snapShot.exists) {
print('does not exist');
} else {
await getData(docuID, 'Washing');
}
setState(() {});
});
}
getData(docuID, machineName) async {
return await firestore()
.collection('environments')
.doc(docuID)
.collection(machineName)
.doc('monday')
.get()
.then((val) {
timeDetails.addAll(val.data());
}).whenComplete(() {
object.add('Mo-$machineName-${timeDetails['timeslots'].values}');
print(object);
setState(() {});
});
}
This also happens in debugPrint. Would anyone know why this is happening and how I could solve it? Any help on this would be appreciated!
Neither the workaround as mentioned on Github nor debugPrint worked for me, but I managed to solve this by adding .toList() to my getData function:
getData(docuID, machineName) async {
return await firestore()
.collection('environments')
.doc(docuID)
.collection(machineName)
.doc('monday')
.get()
.then((val) {
timeDetails.addAll(val.data());
}).whenComplete(() {
//toList() is added here to .add
object.add('Mo-$machineName-${timeDetails['timeslots'].values.toList()}');
print(object);
setState(() {});
});
}
Output:
[Mo-Washing-[09:00-10:00, 10:00-11:00, 11:00-12:00, 12:00-13:00, 13:00-14:00, 14:00-15:00, 15:00-16:00, 16:00-17:00, 17:00-18:00, 18:00-19:00, 19:00-20:00, 20:00-21:00, 21:00-22:00]
I am developing a login system, using firebase, flutter and vscode.
I would like to know how to handle exceptions generated by Firebase.
If EMAIL is already registered.
Currently generating an error:
Exception has occurred.
PlatformException (PlatformException(ERROR_EMAIL_ALREADY_IN_USE, The email address is already in use by another account., null))
If the email is already registered, I want to inform the user.
CODE:
Future<void> signUp({#required Map<String, dynamic> userData,#required String pass,#required VoidCallback onSuccess,#required VoidCallback onFail}) async{
isLoading = true;
notifyListeners();
_auth.createUserWithEmailAndPassword(
email: userData["email"],
password: pass
).then((user) async{
firebaseUser = user;
await _saveUserData(userData);
onSuccess();
isLoading = false;
notifyListeners();
}).catchError((e){
print(e);
onFail();
isLoading = false;
notifyListeners();
});
}
If you want to perform subsequent operations when ERROR_EMAIL_ALREADY_IN_USE is emitted.
I think it's a good idea to catch a PlatformException and branch the process with code as shown below.
try {
final result = await _auth.createUserWithEmailAndPassword(
email: email,
password: password,
);
} on PlatformException catch (exception) {
switch (exception.code) {
case 'ERROR_EMAIL_ALREADY_IN_USE':
// do something...
default:
break;
}
use on PlatformException catch (e) and if (e.message == 'ERROR_EMAIL_ALREADY_IN_USE') to handle this case.