I am experiencing a strange behavior with my Firestore account, on the console I select a collection then I click Delete all documents an it indicates that all have been deleted successfully. When I refresh the data, the collection appear with all the deleted data. I have no service doing this anywhere and wondering what may cause this. Is there a solution?
Alongside this, any change I do to the document fields on the console are successful but are lost after refreshing.
I experienced similar behaviour today that I haven't seen before. I deleted documents from the Firestore console but my app was still fetching them successfully. Now, about an hour after witnessing that behaviour everything is back to normal and my console deletes are immediately seen on the device.
I'm thinking it was a glitch in Firestore - after all it's still in Beta.
I tried all possible means, I had to back up the whole Firestore DB in Json files then deleted the project from console and created a new one. I think It's an issue with Firestore since I created the project before the launch of Firestore and may have required to create a new one.
This happened to me today (7/1/18). After completely logging out of firebase and then logging back in, I was able to delete documents and have them be permanently removed.
It happens because your app is using the cache memory instead of the actual data. You'll have to disable the cache and re-enable the network.
For iOS:
// disable cache
let settings = FirestoreSettings()
settings.isPersistenceEnabled = false
let db = Firestore.firestore()
db.settings = settings
// call your queries inside this layer
Firestore.firestore().enableNetwork { (error) in
// Do online things
}
For Android/Java:
// disable cache
FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder()
.setPersistenceEnabled(false)
.build();
db.setFirestoreSettings(settings);
// enable network
db.enableNetwork()
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
// Do online things
// ...
}
});
You can read more at https://firebase.google.com/docs/firestore/manage-data/enable-offline
Related
so we stumbled over the issue that we hit the quota limit for stored firestore security rules of 2500. During deployment the CLI asks us if we want to delete the oldest 10 rules. Since we want to automate our deployment reacting to a console prompt is not exactly what we want.
Anyone knows how to mass delete the complete firestore security rule history without having to do it manually one by one trough firebase?
I couldn't find any info on that whatsoever from Googles side...
Not sure if you can delete all security rules at once, but as per the documentation, you can avoid manual work by creating a logic to delete the oldest rules:
For example, to delete ALL rule sets deployed for longer than 30 days:
const thirtyDays = new Date(Date.now() - THIRTY_DAYS_IN_MILLIS);
const promises = [];
allRulesets.forEach((rs) => {
if (new Date(rs.crateTime) < thirtyDays) {
promises.push(admin.securityRules().deleteRuleset(rs.name));
}
});
await Promise.all(promises);
console.log(`Deleted ${promises.length} rulesets.`);
I would like to know if this action that I am doing in my application generates expenses for Firebase Storage. That is,
if regardless of the times I do the following action it will generate some expense in Firebase billing.
I have images stored in storage, and I upload these images to an ImageView using the Glide library, like this:
Uri url = Uri.parse(pictureUser);
Glide.with(MainActivity.this).load(url).into(imageView);
I have a chat application, and in each message on the adapter I want to upload the user's photo this way, using Glide, so, as there are many uploads, I wanted to know if every time I run this code snippet, it generates some billing expenses of the firebase.
As you are using this in chat activity this means that same image may probably load many of times.
To decrease the number of images that download I suggest you to use instead of:
Glide.with(MainActivity.this).load(url).into(imageView);
replace it by :
Glide.with(MainActivity.this)
.load(url).diskCacheStrategy(DiskCacheStrategy.DATA)
.into(imageView);
by this way, you are activating the cache mode. this means the Glide will search in the cache if it exists then will upload it from the internet.
I advise you to use Picasso instead of Glide. it works better in mode offline than Glide:
Picasso.with(MainActivity.this)
.load(url)
.networkPolicy(NetworkPolicy.OFFLINE)
.into(imageView, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
// Try again online if cache failed
Picasso.with(MainActivity.this)
.load(url)
.error(R.drawable.user_placeholder_error)
.into(imageView);
}
});
Any time your code download a file, it will be billed as egress from Cloud Storage.
With Glide, it as a disk cache enabled by default, so it should only download a URL once and reuse it from cache (as long as it remains in cache). That would not be billed, since it's not downloading anything from the cloud.
In my Flutter/Dart mobile app I make use of Firebase RTDB persistence to enable offline use of the app.
My understanding is that to enable persistence you have to make the call, as per the following piece of code, before using any database references to eg. query the database. I use the following piece of code to enable persistence immediately after loading the app and it works fine:
FirebaseDatabase firebaseDatabase = FirebaseDatabase.instance;
bool _success = await firebaseDatabase.setPersistenceEnabled(true);
print(_success); // Prints true, so persistence is set 'on'.
When I logout of the app I attempt to turn persistence off with:
bool _success = await firebaseDatabase.setPersistenceEnabled(false);
print(_success); // Prints false, so persistence is still 'on', ie. the call failed.
I assume the reason persistence cannot be turned off is because there have been calls to db references prior to trying to switch it off.
This leads to three questions, I guess:
Should I be worried about turning it off at all, when I logout? The reason I attempt it is good house-keeping, mainly. I clean up shared preferences, close keepsyncd's, etc when logout is run. Also, though, the user can have multiple userids to login and I want to make sure that I am not retaining persisted data from their previous login id.
Related to 1, does setting persistence to false clear the cache of
data and potential queued calls to the db?
If the answers to 1 and 2 are 'yes', how can I switch persistence off given the code I'm using to do so keeps telling me it failed?
The typical way to handle this is to enable persistence once a user logs in.
Once disk persistence has been enabled and your app has used the database, it cannot be turned off. The documentation says this about it:
The returned Future will complete with true if the operation was successful or false if the persistence could not be set (because database references have already been created).
That last bit is clearly the case for you: you've been using the database already, which means that disk persistence is on.
To your specific questions:
Unfortunately the data in the local cache cannot be cleared up through the API at the moment. It is a valid feature request, but for now you'll have to assume that any data on the device can be seen by any user on that device (or device profile).
Disabling disk persistence keep the client from adding data to the cache. It does not clear any existing data in the cache.
I have a NativeScript (Angular) app that makes API-calls to a server to get data. I want to implement a bi-directional synchronization once a device gets online but using current API, no BaaS.
I could do a sort of caching. Once in a while app invalidates info in database and fetches it again. I don't like this approach because there are big lists that may change. They are fetched in batches, i.e. by page. One of them is a list of files downloaded to and stored on a device. So I have to keep those that are still in the list, and delete those that are not. It sounds like a nightmare.
How would you solve such a problem?
I use nativescript-couchebase plugin to store the data. We have following services
Connectivity
Data
API Service
Based on connectivity is Online/Offline, we either fetch data from remote API or via couchebase db. Please note that API service always returns the data from Couchebase only.
So in online mode
API Call -> Write to DB -> Return latest data from Couchebase
Offline mode
Read DB -> Return latest data from Couchebase
Also along with this, we maintain all API calls in a queue. So whenever connectivity returns, API calls are processed in sequence. Another challenge that you may face while coming in online mode from offline mode is the token expiry. This problem can be solved by showing a small popup to user after you come online.
I do this by saving my data as a json string and saving it to the devices file system.
When the app loads/reloads I read it from the file.
ie.
const fileSystemModule = require("tns-core-modules/file-system");
var siteid = appSettings.getNumber("siteid");
var fileName = viewName + ".json";
const documents = fileSystemModule.knownFolders.documents();
const site_folder = documents.getFolder("site");
const siteid_folder = site_folder.getFolder(siteid.toString());
const directoryPath = fileSystemModule.path.join(siteid_folder.path, fileName);
const directoryFile = fileSystemModule.File.fromPath(directoryPath);
directoryFile.writeText(json_string)
.then((result) => {
directoryFile.readText().then((res) => {
retFun(res);
});
}).catch((err) => {
console.log(err.stack);
});
Due to the flow of my app I'm forced to call keepSynced(true) on the same ref every time the user opens the app. I was wondering if it's bad to do so or if Firebase just ignores any redundant keepSynced() calls on the same ref.
How about calling keepSynced(true) on a sub-ref of a ref you already called keepSynced(true) on, are those ignored too?
I'm really looking for a conclusive answer.
keeySynced is either on or off for a path given by a reference. There is no "multiple keepSynced" state - that would be pointless to implement inside the SDK since there is no advantage to doing so.
You only need to call keepSynced(true) once. The way I implement it is to extend the Application Class.
public class GlobalApp extends Application {
#Override
public void onCreate() {
super.onCreate();
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
FirebaseDatabase.getInstance().getReference().keepSynced(true);
}
}
Calling keepSynced(true) on a node ensures that the Firebase Database client will synchronize that node whenever it has a connection to the database servers. There is no built-in API to keep a node synchronized when there is no such connection.
keepSynced(true);
will be useful if we enable offline support
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
If we set keepSynced(true), then whenever a user's internet connection is online, it will update it's node data. More explanation can be read in here
For example : if other user delete the node, than if another user offline. The offline user data will still exist if we're not setting the keepSynced(true).
In some case it will make a force close.
So My conclusion is, either we didn't support offline database,
or support offline but with keepSynced(true). There is also another option, we can choose whenever to keepSynced true or false.