firestore keyword working in the code in flutter - firebase

Hi guys i am trying write firestore.instance but it give error. I can not under stand why this error occur in the below code.
void _fetchMarkersFromDb() {
// TODO: improve this
print('_fetchMarkersFromDb() called');
***Firestore***.instance.collection('markers').getDocuments().then((docs) async {
final docLength = docs.documents.length;
final clients = List(docLength);
for (int i = 0; i < docLength; i++) {
clients[i] = docs.documents[i];
}
if (!isFirstCycle && isMyMarkerFetched) {
currentLocation = await Geolocator.getCurrentPosition();
}
_populateMarkers(clients);
});
}
enter image description here

Use FirebaseFirestore instead.
Like:
FirebaseFirestore.instance.collection('markers').get().then((value) async {
var docs = value.docs;
final docLength = docs.length;
final clients = List(docLength);
for (int i = 0; i < docLength; i++) {
clients[i] = docs[i];
}
if (!isFirstCycle && isMyMarkerFetched) {
currentLocation = await Geolocator.getCurrentPosition();
}
_populateMarkers(clients);
});
To delete a document use:
FirebaseFirestore.instance.collection('markers').doc(documentId).delete()

Related

Problems with RedisLock implemetation by using StackExchange.Redis

I want to implement RedisLock usning StackExchange.Redis library.
By following this article:
https://www.c-sharpcorner.com/article/creating-distributed-lock-with-redis-in-net-core/
How do I need to block a Redis stream.
How do I need to unlock Redis stream. Do I really need to use a script to remove an object from a stream, maybe another programm want to handle current element?
Problem with runing script, but every pass of the loop the programm can't realise the lock but next pass is able to get access to locked stream:
My implementation:
Implementation of RedisLock the same as in article.
public async void ListenTask()
{
var handledResult = await db.StreamRangeAsync(streamName, "-", "+", 1, Order.Descending);
var lowestHandledId = handledResult.Last().Id;
var readTask = Task.Run(async () =>
{
while (!Token.IsCancellationRequested)
{
var result = await db.StreamRangeAsync(streamName, lowestHandledId, "+", 2);
var handleResult = result.Last();
if (result.Any() && lowestHandledId != handleResult.Id)
{
bool isLocked = RedisLock.AcquireLock(streamName, handleResult.Id.ToString(), expiry);
if (!isLocked)
{
//lock
lowestHandledId = handleResult.Id;
var streamCat = handleResult.Values;
Cat cat = ParseResult(streamCat);
switch (streamCat[0].Value.ToString())
{
case "insert":
Console.WriteLine($"Insert cat at id:{cat.Id} [{cat.Name} - {cat.CreatedDate}]");
cacheDictionary.Add(cat.Id, new WeakReference(cat));
break;
case "delete":
Console.WriteLine($"Deleted cat at id:{cat.Id}");
cacheDictionary.Remove(cat.Id);
break;
}
RedisLock.ReleaseLock(streamName, handleResult.Id.ToString());
}
}
await Task.Delay(2000);
}
});
}
I solve my problems with RedisLock implemetation by using LockTake/LockRelease commands.
By following this article:
stackoverflow question
public async void ListenTask()
{
var handledResult = await db.StreamRangeAsync(streamName, "-", "+", 1, Order.Descending);
var lowestHandledId = handledResult.Last().Id;
RedisValue token = Environment.MachineName;
var readTask = Task.Run(async () =>
{
while (!Token.IsCancellationRequested)
{
var result = await db.StreamRangeAsync(streamName, lowestHandledId, "+", 2);
var handleResult = result.Last();
if (result.Any() && lowestHandledId != handleResult.Id)
{
if (!db.LockTake(streamName, token, expiry))
{
lowestHandledId = handleResult.Id;
var streamCat = handleResult.Values;
Cat cat = ParseResult(streamCat);
switch (streamCat[0].Value.ToString())
{
case "insert":
Console.WriteLine($"Insert cat at id:{cat.Id} [{cat.Name} - {cat.CreatedDate}]");
cacheDictionary.Add(cat.Id, new WeakReference(cat));
break;
case "delete":
Console.WriteLine($"Deleted cat at id:{cat.Id}");
cacheDictionary.Remove(cat.Id);
break;
}
db.LockRelease(streamName, token);
}
}
await Task.Delay(100);
}
});
}

How to cancel Flutter RealTime Database Transactions

I have a firebase object that a user increments but can't increment to a certain number.
I want to have a condition in the transaction to prevent the user from incrementing past a set number.
How do I cancel the transaction and return an error to the user i.e
try {
int setLimit = 12; //example limit... Can vary
final TransactionResult transactionResult = await myRef.runTransaction((MutableData mutableData) async {
var currentValue = mutableData.value ?? 0;
if (currentValue >= setLimit) {
throw 'full'; // .... how do I return from this (return throws error ... Expects MutableData)
}
mutableData.value = (mutableData.value ?? 0) + 1;
return mutableData;
});
Adding the transactionResult handlers seems to work
int setLimit = 12;
final TransactionResult transactionResult = await myRef.runTransaction((MutableData mutableData) async {
var currentValue = mutableData.value ?? 0;
if (currentValue >= setLimit) {
throw 'full';
}
mutableData.value = (mutableData.value ?? 0) + 1;
return mutableData;
});
if (transactionResult.committed) {
return transactionResult.dataSnapshot.value;
} else {
if (transactionResult.error != null) {
return transactionResult.error.details;
} else {
return 'full';
}
}

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;
});
}
});

Flutter Firebase update will not stop updating node?

I'm searching for an int value in my firebase node and decreasing it. It successfully decreases and prints the correct info to my log once. When I attempt to update the node with the new int it repeats as if it where in a loop. How can I get it to update a single time? Here is my code...
if (vidRank == 1) {
await fb.child('UserVideo/${userid}/Vid1').onValue.listen((Event event){
if (event.snapshot != null){
var vid1id = event.snapshot.value['videoID'].toString();
fb.child('NumberOnes/${vid1id}').onValue.listen((Event onesEvent){
if (onesEvent.snapshot != null){
var onesValue = (onesEvent.snapshot.value['Value'] as int);
final vidValue = onesValue - 1;
print("Inside ${vidValue}");
fb.child('NumberOnes/${vid1id}').update({
'Value': vidValue
});
}
});
}
});
If you only want a single action, use .once()
if (vidRank == 1) {
var event = await fb.child('UserVideo/${userid}/Vid1').once();
if (event.snapshot != null){
var vid1id = event.snapshot.value['videoID'].toString();
var onesEvent = await fb.child('NumberOnes/${vid1id}').once();
if (onesEvent.snapshot != null){
var onesValue = (onesEvent.snapshot.value['Value'] as int);
final vidValue = onesValue - 1;
print("Inside ${vidValue}");
fb.child('NumberOnes/${vid1id}').update({
'Value': vidValue
});
}
}
}
otherwise an update will cause another event for listen(...) and you have a perfect loop.

GWT read mime type client side

I'm trying to read the mime type in GWT client side in order to validate a file before upload it. To do this I use JSNI to read the file header using HTML5 filereader API. However my problem is that GWT does not wait for the result of the reading and continue the code execution. The side effect is that my boolean is not set yet and my condition goes wrong. Is there any mechanism like promise implemented in GWT?
Any help on this would be much appreciated!
UploadImageButtonWidget.java
private boolean isMimeTypeValid = false;
private String mimeType = null;
public native boolean isValid(Element element)/*-{
var widget = this;
var files = element.files;
var reader = new FileReader();
var CountdownLatch = function (limit){
this.limit = limit;
this.count = 0;
this.waitBlock = function (){};
};
CountdownLatch.prototype.countDown = function (){
this.count = this.count + 1;
if(this.limit <= this.count){
return this.waitBlock();
}
};
CountdownLatch.prototype.await = function(callback){
this.waitBlock = callback;
};
var barrier = new CountdownLatch(1);
reader.readAsArrayBuffer(files[0]);
reader.onloadend = function(e) {
var arr = (new Uint8Array(e.target.result)).subarray(0, 4);
var header = "";
for (var i = 0; i < arr.length; i++) {
header += arr[i].toString(16);
}
widget.#com.portal.client.widgets.base.UploadImageButtonWidget::setMimeType(Ljava/lang/String;)(header);
barrier.countDown();
}
return barrier.await(function(){
return widget.#com.portal.client.widgets.base.UploadImageButtonWidget::isMimeTypeValid();
});
}-*/
public void setMimeType(String headerString) {
boolean mimeValid = true;
if (headerString.equalsIgnoreCase(PNG_HEADER)) {
mimeType = PNG_MIMETYPE;
} else if (headerString.equalsIgnoreCase(GIF_HEADER)) {
mimeType = GIF_MIMETYPE;
} else if (headerString.equalsIgnoreCase(JPG_HEADER1) || headerString.equalsIgnoreCase(JPG_HEADER2) || headerString.equalsIgnoreCase(JPG_HEADER3)) {
mimeType = JPG_MIMETYPE;
} else {
mimeValid = false;
setValidationError(i18n.uploadErrorNotImageBasedOnMimeType());
fileChooser.getElement().setPropertyJSO("files", null);
setErrorStatus();
}
setMimeTypeValid(mimeValid);
}
public boolean isMimeTypeValid() {
GWT.log("mimeType" + mimeType);
GWT.log("isMimetypeValid" + String.valueOf(isMimeTypeValid));
return mimeType != null;
}
in the activity:
public void validateAndUpload() {
UploadImageButtonWidget uploadImageButtonWidget = view.getUpload();
if (uploadImageButtonWidget.isValid()) {
GWT.log("mime ok: will be uploaded");
uploadImage();
} else {
GWT.log("mime not ok: will not be uploaded");
}
}

Resources