So I have this function to store user into Firestore after he successfully registers.
//User class
id: String
email: String?
displayName: String?
photoUrl: String?
//updateOrInsertUser method
collectionReference.document(user.id)
.set(
user,
SetOptions.mergeFields(
FIELD_photoUrl,
FIELD_email,
FIELD_displayName
)
)
But when I call updateOrInsertUser(user) only fields that are in SetOptions are stored in Firestore, therefore id is not stored.
Is there a simple way to override old values defined in SetOptions if the document already exists and if there is not doc store everything?
I don't want to fetch old document before updating :(
No I don't want to add id into SetOptions(imagine other use cases when you don't want to override field that already exists in database)
But when I call updateOrInsertUser(user) only fields that are in SetOptions are stored in firestore, therefore id is not stored.
This is the normal behaviour since you aren't passing the id to the SetOptions's mergeFields() method.
Is there a simple way to override old values defined in SetOptions if the document already exists and if there is not doc store everything? I don't want to fetch old document before updating :(
The simplest way would be to get the "old" document, change its values and write it back to the database but there is also another approach that can help you change the values within a document and this is by using a Map along with a update() method call. In code, might look like this:
Map<String, Object> user = new HashMap<>();
user.put("photoUrl", FIELD_photoUrl);
user.put("email", FIELD_email);
user.put("displayName", FIELD_displayName);
userDocumentReference.update(user);
Related
may I know is there any way to access the Auto-Generate document ID in Firestore using Java? Because I want to add new field and data to existing document through my own android app. I have gone through the documentation, but didn't find any that solve the problem.
Elaboration of problem: I try to obtain the auto-generate ID of each "Event" document for the purpose of adding/update new field "Save Event" for each "User" in Firestore. So that 1 user can save many "event" inside the firestore.
In order to use the document ID that you are looking for, first, you need to store it in a variable. When you are adding a document to the database and you are using a document() method call without passing any arguments, a unique ID is generated. To get that ID, you should use the following code:
String docId = collRef.document().getId();
collRef.document(docId).set(obj);
In which "collRef" is a reference that points to the collection in which you want to add the document, and the "obj" is the object that you want to be added to the database.
If needed, you can also store the document ID, as a property of your object.
Once you have this ID, you can perform the update like this:
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference collRef = rootRef.collection("collName");
collRef.document(docId).update(map).addOnCompleteListener(/* ... /*);
How to query data from collection where document reference contain specific path?
Here is my Firestore database, filed user is a document reference type, mapped document reference form other collection.
Here I need to get all data from userinfo collection where user document reference contains specific path (eg : player/8SLuNWrI09UIuUfNe7ZR/playerinfo )
I have tried following query but seems not working:
Query query = mFirebaseFirestore.collection("userinfo").whereGreaterThanOrEqualTo("user", "player/8SLuNWrI09UIuUfNe7ZR/playerinfo");
Code to get data from query:
query.addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(QuerySnapshot queryDocumentSnapshots, FirebaseFirestoreException e) {
//queried data here
}
});
No example available on document to query Firestore with document reference type.
Please help me to query list of document from collection where document reference having specific path.
Thanks in advance
You don't find any examples in the official documentation of Firestore because unfortunately, there is no contains() method which can help you verify if a String is apart of a reference, which is a property of a document.
However, if you want to get all document that exist under playerinfo collection, then just use a get() call. Don't use addSnapshotListener() unless you need to get data in real-time.
There is a solution in which you need to transform your user property to be of type String and use a query that look like this:
Query query = = mFirebaseFirestore.collection("userinfo").whereEqualTo("user", "player/8SLuNWrI09UIuUfNe7ZR/playerinfo");
But rememeber, this will work only if the property user holds a value of type String which is equal to:
player/8SLuNWrI09UIuUfNe7ZR/playerinfo`
and not:
player/8SLuNWrI09UIuUfNe7ZR/playerinfo/qY0D7Vef...
^ ^
There is one more in way in which you can solve this. Query the entire collection, get all the values of user property and add them to a List by converting them from Reference to String. In the end, just iterate over the list and use contains() method on each element.
You just want to get the document by its location in the database:
mFirebaseFirestore.collection("userinfo").document("8SLuNWrI09UIuUfNe7ZR").get()
No need for a query if you know the specific document to fetch.
I'm inserting objects into MongoDB without specifying the _ids, because I want it to create them automatically. The problem is that at a certain point of the program I need to retrieve the _ids, but I can't get them. The code I use is the following:
List<DBObject> objs=collection.find(filter).toArray();
BDObject obj=objs.get(0);
String id=obj.get("_id");
//now id is something like 2d938830-2732-44fd-84b0-aa56b95c5df0
Eventually the id variable contains a GUID, but it's different from the one I see in RoboMongo, so it's wrong. What I see in RoboMongo is something like:
"_id": LUUID("cada0d4f-a72d-47ad-8ea8-239c3e5795dd")
How can I find a document and retrieve it if found, but insert and retrieve it if not found in one command?
I have an outline for the formats I wish my documents to look like for a user's data. Here is what it looks like
{
"username": "HeyAwesomePeople",
"uuid": "0f91ede5-54ed-495c-aa8c-d87bf405d2bb",
"global": {},
"servers": {}
}
When a user first logs in, I want to store the first two values of data (username and uuid) and create those empty values (global and servers. Both those global and servers will later on have more information filled into them, but for now they can be blank). But I also don't want to override any data if it already exists for the user.
I would normally use the insertOne or updateOne calls to the collection and then use the upsert (new UpdateOptions().upsert(true)) option to insert if it isn't found but in this case I also need to retrieve the user's document aswell.
So in a case in which the user isn't found in the database, I need to insert the outlined data into the database and return the document saved. In a case where the user is found in the database, I need to just return the document from the database.
How would I go about doing this? I am using the latest version of Mongo which has deprecated the old BasicDBObject types, so I can't find many places online that use the new 'Document' type. Also, I am using the Async driver for java and would like to keep the calls to the minimum.
How can I find a document and retrieve it if found, but insert and retrieve it if not found in one command?
You can use findOneAndUpdate() method to find and update/upsert.
The MongoDB Java driver exposes the same method name findOneAndUpdate(). For example:
// Example callback method for Async
SingleResultCallback<Document> printDocument = new SingleResultCallback<Document>() {
#Override
public void onResult(final Document document, final Throwable t) {
System.out.println(document.toJson());
}
};
Document userdata = new Document("username","HeyAwesomePeople")
.append("uuid", "0f91ede5")
.append("global", new Document())
.append("servers", new Document());
collection.findOneAndUpdate(userdata,
new Document("$set", userdata),
new FindOneAndUpdateOptions()
.upsert(true)
.returnDocument(ReturnDocument.AFTER),
printDocument);
The query above will try to find a document matching userdata; if found set it to the same value as userdata. If not found, the upsert boolean flag will insert it into the collection. The returnDocument option is to return the document after the action is performed.
The upsert and returnDocument flags are part of FindOneAndUpdateOptions
See also MongoDB Async Java Driver v3.4 for tutorials/examples. The above snippet was tested with current version of MongoDB v3.4.x.
What is the best method to get the Mongo generated ID of a document inserted via Java.
The Java process inserting the documents is multi-thread, meaning that we need some atomic way to insert and return the ID of the object.
Also, if we setup a unique index, in the event that the object is a duplicate, will an ID be returned?
Thanks!
Generate the ObjectId early, use it in the insert, and there will no need to have the database return it to you.
ObjectId doesn't use a shared sequence number to be unique, so it doesn't matter if you generate one before inserting or retrieve it after.
public ObjectId createThing() {
ObjectId result = new ObjectId();
BasicDBObject thingToInsert = new BasicDbObject();
thingToInsert.put('_id', result);
//set other fields here
collection.insert(thingToInsert);
return result;
}
native ObjectId's which are generated by Mongo are globally unique and can be safely used from the multi-threaded application.
generated ObjectId can be obtained from the DbObject under _id key.
If inserted document violates a unique index constraint - java driver may throw an exception, depending on a value of WriteConcern:
http://api.mongodb.org/java/current/com/mongodb/WriteConcern.html
If it's value is higher then NORMAL- exception will be thrown.
WriteConcern can be specified for every individual insert (or update) method, or globally by using DBCollection.setWriteConcern
I retrieve the document with _id but when I get the data into my java class eg mobile, _id attribute which is of type ObjectID me I change it set the value of the document in mongodb.