Check if document exists, if not create and add data Firebase - firebase

As above I need create a function that returns "true" if a document exists, otherwise "false".
If the document doesn't exists then It need to be created before the function ends.
When I run it I have this exception :
Unhandled Exception: 'package:cloud_firestore/src/firestore.dart': Failed assertion: line 129 pos 12:
'isValidDocumentPath(documentPath)': a document path must point to a valid document.
Is pretty easy to understand that I'm not checking if the path exists before getting the collection but I don't know how to handle it.
This is the code:
Future<bool> checkMissingId(String id) async {
String str = id.toLowerCase();
String letter = str[0];
final snapShot =
await FirebaseFirestore.instance.collection(letter).doc(str).get();
if (snapShot == null || !snapShot.exists) {
//if not exists then create it
final _service = FirestoreService.instance;
_service.setData(
path: letter + str,
data: {'id': id},
);
return true;
} else // it already exists, return false
return false;
}
EDIT : new code but still doesn't work :
Future<bool> checkMissingId(String id) async {
String str = id.toLowerCase();
String letter = str[0];
String path = letter + "/" + str;
print(path);
try {
final snapShot =
await FirebaseFirestore.instance.collection(path).doc(str).get();
if (snapShot == null || !snapShot.exists) {
return true;
} else
return false;
} catch (e) {
print(e);
return false;
}
}
Future<bool> setId(String id) async {
String str = id.toLowerCase();
String letter = str[0];
String path = letter + "/" + str;
final _service = FirestoreService.instance;
try {
final snapShot =
await FirebaseFirestore.instance.collection(path).doc(str).get();
if (snapShot == null || !snapShot.exists) {
_service.setData(
path: path,
data: {'id': id},
);
return true;
} else
return false;
} catch (e) {
//print(e);
_service.setData(
path: path,
data: {'id': id},
);
return true;
}
}
Assuming id = "PaninoAvvelenato" :
I want to check if exists the document on path "p/paninoavvelenato", if not I need to create it.

Instead of using FirestoreService.
Future<bool> setId(String id) async {
String str = id.toLowerCase();
String letter = str[0];
try {
final snapShot = await FirebaseFirestore.instance.collection(letter).doc(str).get();
if (snapShot.exists) {
return false;
} else {
await FirebaseFirestore.instance.collection(letter).doc(str).set({'id': id});
return true;
}
} catch (e) {
// TODO: Do something clever.
return true;
}
}

It looks like document for path str is not exist and FirebaseFirestore.instance.collection(letter).doc(str).get(); throw exception
so better to place this code inside :
try {
// code that might throw an exception
FirebaseFirestore.instance.collection(letter).doc(str).get();
}
on Exception1 {
// code for handling exception
}
catch Exception2 {
// code for handling exception
}

Related

Return Boolean from Task, That checks if string exist in Firebase Realtime Database

The Task passes through the two strings from getuser() on to DBFirebase class. It then uses those strings to check if they exist in The Firebase Realtime Database. How can i return "CheckLogin" to Loginpage?. I tried changing the task to Task, but then it prevents the string from sending to the DB. Any Suggestions?
//LoginPage.xaml.cs
public async void getuser()
{
await services.LoginCheck(EmailEntry.Text, PasswordEntry.Text);
}
//DBFirebase.cs
public async Task LoginCheck(string email, string password)
{
var LoginCheck = (await Client.Child("users").OnceAsync<users>()).FirstOrDefault(a => a.Object.email == email && a.Object.password == password);
if (LoginCheck == null)
{
CheckLogin = false;
}
else
{
CheckLogin = true;
}
public async Task<bool> LoginCheck(string email, string password)
{
bool CheckLogin = false;
var LoginCheck = (await Client.Child("users").OnceAsync<users>()).FirstOrDefault(a => a.Object.email == email && a.Object.password == password);
if (LoginCheck == null)
{
CheckLogin = false;
}
else
{
CheckLogin = true;
}
return CheckLogin;
}
to call it
var check = await services.LoginCheck(EmailEntry.Text, PasswordEntry.Text);

A value of type 'Future<String>' can't be assigned to a variable of type 'String'

I have this code where am supposed to upload an image and get the downloaded url but whenever i do that I get this error
my url is String url;. So please why is this not working as it is supposed to
PS
I checked other website to learn how to properly upload but it keeps giving me an error or is there a better way to do this.
My code image
uploadTask.whenComplete(()async{
url = await refs.getDownLoadURL();
....
});
Since it returns a Future you need to wait for it to be accessed
Example :
Future<String> createFolder(String folderName) async {
final dir = Directory(
'${(io.Platform.isAndroid ? await getExternalStorageDirectory() //FOR ANDROID
: await getApplicationSupportDirectory() //FOR IOS
)!.path}/$folderName');
var status = await Permission.storage.status;
if (!status.isGranted) {
await Permission.storage.request();
}
if ((await dir.exists())) {
return dir.path;
} else {
dir.create();
return dir.path;
}
}
Future<String> getIslamiSahittoBookFilePath(String savename) async {
Future<String> s = createFolder("Islami_Sahitto");
String filePath = await s;
Map<Permission, PermissionStatus> statuses = await [
Permission.storage,
//add more permission to request here.
].request();
io.File? f = null;
if (statuses[Permission.storage]!.isGranted) {
Directory? dir = await DownloadsPath.downloadsDirectory();
if (dir != null) {
String savePath = "${dir.path}/$filePath/$savename";
f = new io.File(savePath);
if (await f.exists()) {}
}
}
return f.toString();
}
Now this block You can use AnyWhere : Future String, to String :
bool isPreviousDownloaded = false;
String previousFilePath = "null";
getIslamiSahittoBookFilePath(fileNameToDownload).then((value) {
if (value != null) {
setState(() {
isPreviousDownloaded = true;
previousFilePath = value;
});
}
});

Can't assign a data value to a string - returns null - flutter

In my code, am trying a assign a string value to an empty string and display on the page but it keeps showing null but when I print it out, it shows the value.
String fName = '';
#override
void initState() {
super.initState();
getData();
}
getData() async {
FirebaseAuth _auth = FirebaseAuth.instance;
User _firebaseUser = _auth.currentUser;
print("============ MyHome ================");
print(_firebaseUser.uid);
_currentUser = await Database().getUserData(_firebaseUser.uid);
if (_currentUser != null) {
fName = _currentUser.firstName;
print(_currentUser.firstName);
}
}
database
Future<UserData> getUserData(String uid) async {
UserData returnValue = UserData();
try {
DocumentSnapshot _docSnapshot =
await _firestore.collection("users").doc(uid).get();
returnValue.uid = uid;
returnValue.firstName = _docSnapshot.data()["firstName"];
returnValue.lastName = _docSnapshot.data()["lastName"];
returnValue.userMail = _docSnapshot.data()["userMail"];
returnValue.userType = _docSnapshot.data()["userType"];
print("====================== on getData =============");
print(returnValue.firstName);
} catch (e) {
print(e);
}
return returnValue;
}
And whenever I try displaying the data it gives me null
Text("Hello, $fName"),
Please how do I do this or am I missing something
use setState to rebuild the widget tree with the value:
setState(() {
fName = _currentUser.firstName;
});
Since the getData function is async, flutter has already built the widget tree before getData finished. You'll now have to update the state using setstate.
setState(() {
fName = _currentUser.firstName;
});
You need to set the new state since we have made changes to the previous state (since your getData function is async.
setState(() {
fName = _currentUser.firstName;
});

Delete Records from a database

I am trying to delete set of records under my ASP.NET Application - API Controller. Here is my code from API Controller:
public JsonResult Delete([FromBody]ICollection<ShoppingItemViewModel> vm)
{
if (ModelState.IsValid)
{
try
{
var items = Mapper.Map<IEnumerable<ShoppingItem>>(vm);
_repository.DeleteValues(items, User.Identity.Name);
return Json(null);
}
catch (Exception Ex)
{
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json(null);
}
}
else
{
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json(null);
}
}
And here is my AngularJS Controller part taking care of this:
$scope.RemoveItems = function () {
$scope.isBusy = true;
$http.delete("/api/items", $scope.items)
.then(function (response) {
if (response.statusText == "OK" && response.status == 200) {
//passed
for (var i = $scope.items.length - 1; i > -1; i--) {
if ($scope.items[i].toRemove == true) {
$scope.items.splice(i, 1);
}
}
}
}, function (err) {
$scope.errorMessage = "Error occured: " + err;
}).finally(function () {
$scope.isBusy = false;
});
}
For unknown reason, this works like a charm in my POST method but not in the Delete Method. I believe that the problem might be caused by the fact, that DELETE method only accepts Integer ID?
If that is the case, what is the correct way how to delete multiple items with one call?

Asp.Net Identity SMS Verification token ever invalid

I try to verify a phone number with ASP.Net Identity.
Here is my code generation:
public async Task<JsonResult> SendVerifyPhoneNumber()
{
var user = await this.UserManager.FindByIdAsync(User.Identity.GetUserId<int>());
if (user != null)
{
if (!string.IsNullOrWhiteSpace(user.PhoneNumber))
{
if (!await this.UserManager.IsPhoneNumberConfirmedAsync(user.Id))
{
string number = user.PhoneNumber;
if (!string.IsNullOrWhiteSpace(number))
{
number = TelNumber.DecryptUserTelefon(number, ApplicationUser.AES_CRYPTO_KEY);
}
string code = await this.UserManager.GenerateChangePhoneNumberTokenAsync(user.Id, number);
string text = string.Format(ResourcesLocal.Resources_Manage_Index.TelefoncodeNachrichtBestaetigen, code);
bool result = Helper.Services.SmsService.SendSMS(SmSWarteschlangeCon, number, text);
}
}
return Json(true);
}
return Json(false);
}
Where is my Code catch by input:
public async Task<JsonResult> VerifyPhoneNumber(string code)
{
var user = await this.UserManager.FindByIdAsync(User.Identity.GetUserId<int>());
if (user != null)
{
string number = user.PhoneNumber;
if (!string.IsNullOrWhiteSpace(number))
{
number = TelNumber.EncryptUserTelefon(number, ApplicationUser.AES_CRYPTO_KEY);
}
var result = await this.UserManager.ChangePhoneNumberAsync(
user.Id, number, code);
if (result.Succeeded)
{
user = await this.UserManager.FindByIdAsync(user.Id);
if (user != null)
{
await this.SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
}
return Json(true);
}
}
return Json(false);
}
But the result fail every time with "Invalid token" even if the code is the same and given within seconds...
Any ideas?

Resources