Here is my data structure:
I have an ios app that is attempting to access data from Cloud Firestore. I have been successful in retrieving full documents and querying for documents. However I need to access specific fields from specific documents. How would I make a call that retrieves me just the value of one field from Firestore in swift? Any Help would be appreciated.
There is no API that fetches just a single field from a document with any of the web or mobile client SDKs. Entire documents are always fetched when you use getDocument(). This implies that there is also no way to use security rules to protect a single field in a document differently than the others.
If you are trying to minimize the amount of data that comes across the wire, you can put that lone field in its own document in a subcollection of the main doc, and you can request that one document individually.
See also this thread of discussion.
It is possible with server SDKs using methods like select(), but you would obviously need to be writing code on a backend and calling that from your client app.
This is actually quite simple and very much achievable using the built in firebase api.
let docRef = db.collection("users").document(name)
docRef.getDocument(source: .cache) { (document, error) in
if let document = document {
let property = document.get(field)
} else {
print("Document does not exist in cache")
}
}
There is actually a way, use this sample code provided by Firebase itself
let docRef = db.collection("cities").document("SF")
docRef.getDocument { (document, error) in
if let document = document, document.exists {
let property = document.get('fieldname')
print("Document data: \(dataDescription)")
} else {
print("Document does not exist")
}
}
I guess I'm late but after some extensive research, there is a way in which we can fetch specific fields from firestore. We can use the select keyword, your query would be somthing like (I'm using a collection for a generalized approach):
const result = await firebase.database().collection('Users').select('name').get();
Where we can access the result.docs to further retrieved the returned filtered result. Thanks!
//this is code for javascript
var docRef = db.collection("users").doc("ID");
docRef.get().then(function(doc) {
if (doc.exists) {
//gives full object of user
console.log("Document data:", doc.data());
//gives specific field
var name=doc.get('name');
console.log(name);
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
}
}).catch(function(error) {
console.log("Error getting document:", error);
});
Related
I'm trying to add pagination in images data that I'm retrieving from firebase using Firebase Storage. I have 10 images there and I want to display 2 at a time in RecyclerView and when the user scrolls down to end vertically, it loads the next 2 until all the images are displayed, I have also read some documentation of Firebase where it was mentioned to use storage.list(int max results) method but with that, it only shows the number of results that I pass in the method for instance if I pass 2 it shows 2 images only, and I can't load anymore. I've found one method too on the official documentation i.e below: https://firebase.google.com/docs/storage/android/list-files
public void listAllPaginated(#Nullable String pageToken) {
FirebaseStorage storage = FirebaseStorage.getInstance();
StorageReference listRef = storage.getReference().child("files/uid");
// Fetch the next page of results, using the pageToken if we have one.
Task<ListResult> listPageTask = pageToken != null
? listRef.list(100, pageToken)
: listRef.list(100);
listPageTask
.addOnSuccessListener(new OnSuccessListener<ListResult>() {
#Override
public void onSuccess(ListResult listResult) {
List<StorageReference> prefixes = listResult.getPrefixes();
List<StorageReference> items = listResult.getItems();
// Process page of results
// ...
// Recurse onto next page
if (listResult.getPageToken() != null) {
listAllPaginated(listResult.getPageToken());
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
// Uh-oh, an error occurred.
}
});
}
I'm confused about how to use it, I don't know where I can get a page token from in order to provide a reference to open the next page
The thing is I have 200 images in my Firebase Storage and I directly want to apply pagination to the URLs that I'm retrieving from Firebase Storage.
To achieve that, you have two options. The first one would be to use StorageReference#listAll() method which:
List all items (files) and prefixes (folders) under this StorageReference.
And according to the official documentation regarding how to list files with Cloud Storage on Android, please note that:
Cloud Storage for Firebase allows you to list the contents of your Cloud Storage bucket. The SDKs return both the items and the prefixes of objects under the current Cloud Storage reference:
So you have to explicitly differentiate that (items vs. prefixes) in your application code and provide your own pagination algorithm.
The second option that you have, and the simplest one, in my opinion, would be to store the image URLs in the Firestore and implement the pagination as explained here:
Paginate data with query cursors
I want to update a document with a User object that I have, but I do not want the document to be created if it does not exist, and therefore I cannot use "DocumentReference.set" with "SetOptions.Merge()" (to my understanding).
However, according to this post (Difference between set with {merge: true} and update), "update" is actually the command I need. My problem is, it doesn't seem like update accepts a Java object.
I do not want to check whether or not the document exists myself, as this will result in an unnecessary read.
Is there any way around this?
Here is my code (I have removed success and failure listeners for simplicity):
public void saveUser(User user)
{
CollectionReference collection = db.collection("users");
String id = user.getId();
if (id.equals(""))
{
collection.add(user);
}
else
{
// I need to ensure that the ID variable for my user corresponds
// with an existing ID, as I do not want a new ID to be generated by
// my Java code (all IDs should be generated by Firestore auto-ID)
collection.document(ID).set(user);
}
}
It sounds like you:
Want to update an existing document
Are unsure if it already exists
Are unwilling to read the document to see if it exists
If this is the case, simply call update() and let it fail if the document doesn't exist. It won't crash your app. Simply attach an error listener to the task it returns, and decide what you want to do if it fails.
However you will need to construct a Map of fields and values to update using the source object you have. There are no workarounds for that.
We're developing a Cloud Foundry app with Java that should be able to consume any kind of OData entity. We get a base path from the Destination service, add some path that the user enters, and would like to store the results we get from there.
Does the Cloud SDK offer components that can help with the OData query part? Or do we need to resort to something generic like Olingo?
You can use the ODataQueryBuilder to execute arbitrary OData calls and then process the result manually.
ODataQueryResult result = ODataQueryBuilder
.withEntity("/base/path/to/api" + userPath, userEntity)
.build()
.execute("MyDestination");
How you then proceed with the result depends highly on your use case. If the returned data is of a known type that you can determine at runtime, you could simply retrieve the result as that type. In this example we recieve a list of items:
List<MyClass> resList = result.asList(MyClass.class);
If not, you can process the ResultElements of the request and for instance process json objects:
result.getResultElements().forEach(e -> {
if( e.isResultObject() ) {
JsonObject obj = ((GsonResultObject)e).getJsonObject();
// do some json processing
}
else if( e.isResultCollection() ) {
// do something else
}
else {
System.out.println(e.getAsPrimitive());
}
});
You'll find some information on the ODataQueryBuilder in this blog post. The documentation for ResultElement can be found here.
I have a bunch of sensors scattered around.
These sensors transmit their status whenever they detect a change in their environment.
The data goes to a server(built using Java) where it processes that information then inserts it into a mongoDB.
My meteor App is essentially a dashboard for this information. I would like to do further processing on those entries as soon as they come in (analytics).
I started to use Collection-Hooks which works really nicely when the Meteor App makes changes to the database but not when the mongo Java-Driver does.
I need collection-hooks to detect new documents added to my mongoDB from the Java-driver. I'm also not married to collection-hooks, any other services suggested are welcomed.
What you want to use is an Observer on the cursor returned from a query:
https://docs.meteor.com/api/collections.html#Mongo-Cursor-observe
myCollection.find().observe({
added(document) {
// Do something with new document
},
changed(document) {
// Update analytics in response to change
},
removed(oldDocument) {
// Update analytics in response to change
}
});
This will depend on the contents of the actual database, unlike collection hooks that only operate when Meteor code is called
It's also worth noting that these hooks also track the specific query that was passed to find(). So if you only want to call these hooks for a specific subset of data, pass in the query like this this example from #scriptkid:
var date = moment().utc().format("YYYY-MM-DD HH:mm:ss.SSS");
log.find({ createdAt: { $gte: date } }).observe({
added(document) {
console.log("new document added!");
},
});
I am using a local database in my version of Lotus notes(8.5.2), and I am trying to get the data for two things:
The highlighted document/item in a NotesUIView
The document selected in a NotesUIDocument
However, all I get are the Notes URLs and I don't know what I should do with those. Can anyone help me out/throw me a breadcrumb?
P.S. Yes I am using the Java API for Eclipse.
Here is a code sample of what I do:
NotesUIWorkspace workSpace = new NotesUIWorkspace();
NotesUIElement currentElement = workSpace.getCurrentElement();
if (currentElement instanceof NotesUIView) {
NotesUIView currentView = (NotesUIView) currentElement;
NotesUIViewEntryCollection collection = currentView
.getActionableEntries();
Iterator docIterator = collection.documentIterator();
while (docIterator.hasNext()) {
NotesUIDocumentEntry entry = (NotesUIDocumentEntry) docIterator.next();
//I can't seem to get to the NoesUIDocument case like I can below... I want fields!
}
}
if(currentElement instanceof NotesUIDocument){
NotesUIDocument document = (NotesUIDocument) currentElement;
//Seem to be able to get the correct data fields only in this case!
document.getFields();
}
Fetching the "current" document is usually done via the NotesAgentContext.UnprocessedDocuments. In a view, that might return a collection of documents if the user as ticked several.
If you already have an NotesUIView, NotesUIView.getActionableEntries will give you the selected document(s).
When you have a NotesDocumentData instance, NotesUIWorkspace.openDocument can be used to open it up in edit mode. Then NotesUIWorkspace.getCurrentDocument can be used to get hold of the UI Document.
Notice that if you only want to read values from the document, it is more convenient to use the back-end classes like Document.
Have you got a URL as an example? If it includes the UUID of the document in question then you should be able to reference it directly with a getDocument(). Otherwise, the URL should include a view reference and a lookup key for that view in question.