Writing data to Firebase, Android - java

I have an App which uses Firebase and it uses 'push' to write a record. My problem is with updating the content of that record. Any help very welcome. I am using Firebase Authentication email/password and that works fine. I also have my database in a Java Class which also works fine. In onCreate method I have the data referenced:
databasePropertyData FirebaseDatabase.getInstance().getReference("users");
Using a button I can create a new record with it's unique identifier, which is what I want:
String ownerId = databasePropertyData.push().getKey();
PropertyData propertyData = new PropertyData(ownerId, ownerName, name);
databasePropertyData.child(ownerId).setValue(propertyData);
This code works fine and creates a record with the user id just as I want.
However, I now want to update that particular record and that is where the problems lies. The code I have used (and a myriad variations) sets up a new record rather than updating the existing data. This is one example of my failed experimentation:
String ownerId = databasePropertyData.getKey();
databasePropertyData.child(ownerId).setValue(name,ownerName);
Any help would be much appreciated.

This is happening because you are using the push() method. It generates a new random key every time you are signing in. To solve this, use the uid instead of the pushed key.
PropertyData propertyData = new PropertyData(ownerId, ownerName, name);
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
databasePropertyData.child(uid).setValue(propertyData);
The benefit of using the uid is that you can update the record very easily.
databasePropertyData.child(uid).updateChildren(propertyData);

You can update specified field using updateChild, here is ref:
https://firebase.google.com/docs/database/web/read-and-write#update_specific_fields

You have this in your database:
users
randomid
ownerId: 12345
ownerName: userx
name: anothername
To update you can do this, since you are using push(), then use the variable that has the key in it and do this:
String ownerId = databasePropertyData.push().getKey(); //the variable that has the key, not a new variable
PropertyData propertyData = new PropertyData(ownerId, ownerName, name);
databasePropertyData.child(ownerId).setValue(propertyData);
Or instead of this, you can change the database structure and use user id:
FirebaseUser user=FirebaseAuth.getInstance().getCurrentUser();
PropertyData propertyData = new PropertyData(ownerId, ownerName, name);
databasePropertyData.child(ownerId).setValue(propertyData);
Or you can make a query and retrieve the push() key from the database and update the values in the query.
But you have to update all 3 fields.

String ownerId = databasePropertyData.getKey();
here instead of creating new ownerId, you should use the same Id of the propertyData that you want to update. Then using updateChildren or setValue method, you can update the value.
Then this will work fine:
databasePropertyData = FirebaseDatabase.getInstance().getReference("users");
PropertyData propertyData = new PropertyData(ownerId, ownerName, name);
databasePropertyData.child(ownerId).setValue(propertyData);

Related

How to use UpdateEventSourceMappingRequest in java?

I'm trying to use something like this:
UpdateEventSourceMappingRequest request = new UpdateEventSourceMappingRequest()
.withFunctionName("arn:aws:lambda:us-east-1:9999999999:function:"+functionName)
.withEnabled(false);
But I received a error because I have to use .withUUID(uuid):
UpdateEventSourceMappingRequest request = new UpdateEventSourceMappingRequest()
.withUUID(uuid))
.withFunctionName("arn:aws:lambda:us-east-1:9999999999:function:"+functionName)
.withEnabled(false);
I don't know how to get the value of uuid ( uuid from aws lambda ).
Can you help me with the solution to my problem ?
You need to provide the UUID identifier of the event source mapping to update it (and this field is mandatory). Update-request is not intended to create it.
When you create an event source mapping (here) - aws should return a response with a UUID identifier which you then may use in the update request.
That's the solution that I founded:
String strUUID = "";
ListEventSourceMappingsRequest requestList = new ListEventSourceMappingsRequest()
.withEventSourceArn("arn:aws:sqs:us-east-1:9999999999:test");
ListEventSourceMappingsResult result = awsLambda.listEventSourceMappings(requestList);
List<EventSourceMappingConfiguration> eventSourceMappings = result.getEventSourceMappings();
for (EventSourceMappingConfiguration eventLambda : eventSourceMappings) {
strUUID = eventLambda.getUUID();
}
System.out.println("Output UUID " + strUUID);
We have to use the ARN of the SQS that's trigger of the aws lambda.

AWS - DynamoDB - how to get object that have only one field from DataBase

I'm using DynamoDB, I have table called "cache" with only one field that is String - "apiToken", how can I get this String from DB when I have only that one field? Is this even possible?
private String getAuthToken() {
// TODO: Replace with cache fetched from DB instead of refreshApiToken method
Cache cache = new Cache();
cache.setApiToken(this.refreshApiToken());
return cache.getApiToken();
}
If you only store one item in DynamoDB, I suggest to get rid of DynamoDB at all and use AWS Systems Manager Parameter Store instead.
If you want to stick to DynamoDB you can make a ScanRequest to get the first item.
ScanRequest scanRequest = new ScanRequest()
.withTableName("cache")
.withLimit(1);
ScanResult result = client.scan(scanRequest);
// handle result.getItems() ...

Java driver: how to get the objectId of an updated object with Mongodb's updateFirst method

I'm trying to get the objectId of an object that I have updated - this is my java code using the java driver:
Query query = new Query();
query.addCriteria(Criteria.where("color").is("pink"));
Update update = new Update();
update.set("name", name);
WriteResult writeResult = mongoTemplate.updateFirst(query, update, Colors.class);
Log.e("object id", writeResult.getUpsertedId().toString());
The log message returns null. I'm using a mongo server 3.0 on mongolab as I'm on the free tier so it shouldn't return null. My mongo shell is also:
MongoDB shell version: 3.0.7
Is there an easy way to return the object ID for the doc that I have just updated? What is the point of the method getUpsertedId() if I cannot return the upsertedId?
To do what I want, I currently have to issue two queries which is highly cumbersome:
//1st query - updating the object first
Query query = new Query();
query.addCriteria(Criteria.where("color").is("pink"));
Update update = new Update();
update.set("name", name);
WriteResult writeResult = mongoTemplate.updateFirst(query, update, Colors.class);
//2nd query - find the object so that I can get its objectid
Query queryColor = new Query();
queryColor.addCriteria(Criteria.where("color").is("pink"));
queryColor.addCriteria(Criteria.where("name").is(name));
Color color = mongoTemplate.findOne(queryColor, Color.class);
Log.e("ColorId", color.getId());
As per David's answer, I even tried his suggestion to rather use upsert on the template, so I changed the code to the below and it still does not work:
Query query = new Query();
query.addCriteria(Criteria.where("color").is("pink"));
Update update = new Update();
update.set("name", name);
WriteResult writeResult = mongoTemplate.upsert(query, update, Colors.class);
Log.e("object id", writeResult.getUpsertedId().toString());
Simon, I think its possible to achieve in one query. What you need is a different method called findAndModify().
In java driver for mongoDB, it has a method called findOneAndUpdate(filter, update, options).
This method returns the document that was updated. Depending on the options you specified for the method, this will either be the document as it was before the update or as it is after the update. If no documents matched the query filter, then null will be returned. Its not required to pass options, in that case it will return the document that was updated before update operation was applied.
A quick look at the mongoTemplate java driver docs here: http://docs.spring.io/spring-data/mongodb/docs/current/api/org/springframework/data/mongodb/core/FindAndModifyOptions.html tells me that you can use the method call:
public <T> T findAndModify(Query query,
Update update,
FindAndModifyOptions options,
Class<T> entityClass)
You can also change the FindAndModifyOptions class to take on an 'upsert' if the item was not found in the query.If it is found, the object will just be modified.
Upsert only applies if both
The update options had upsert on
A new document was actually created.
Your query neither has upsert enabled, nor creates a new document. Therefore it makes perfect sense that the getUpsertedId() returns null here.
Unfortunately it is not possible to get what you want in a single call with the current API; you need to split it into two calls. This is further indicated by the Mongo shell API for WriteResults:
The _id of the document inserted by an upsert. Returned only if an
upsert results in an insert.
This is an example to do this with findOneAndUpdate(filter,update,options) in Scala:
val findOneAndUpdateOptions = new FindOneAndUpdateOptions
findOneAndUpdateOptions.returnDocument(ReturnDocument.AFTER)
val filter = Document.parse("{\"idContrato\":\"12345\"}")
val update = Document.parse("{ $set: {\"descripcion\": \"New Description\" } }")
val response = collection.findOneAndUpdate(filter,update,findOneAndUpdateOptions)
println(response)

Deleting Attribute in DynamoDB

I'm trying to figure out the best way to delete an attribute from an item in Dynamo DB. Below is what I tried, but I get an exception saying that DELETE is not a supported for either type N or S.
Exception in thread "main" Status Code: 400, AWS Service: AmazonDynamoDB, AWS Request ID: 09MRO4PVTJ8IK6OHLKSM551REJVV4KQNSO5AEMVJF66Q9ASUAAJG, AWS Error Code: ValidationException, AWS Error Message: One or more parameter values were invalid: Action DELETE is not supported for the type N
at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:544)
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:284)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:169)
at >com.amazonaws.services.dynamodb.AmazonDynamoDBClient.invoke(AmazonDynamoDBClient.java:675)
at >com.amazonaws.services.dynamodb.AmazonDynamoDBClient.updateItem(AmazonDynamoDBClient.java:371)
Key pk = new Key(new AttributeValue().withN(Long.toString(123)));
AttributeValueUpdate avu = new AttributeValueUpdate(new AttributeValue().withN("555"), "DELETE");
Map<String, AttributeValueUpdate> m = new HashMap<String, AttributeValueUpdate>();
m.put(String.valueOf(555), avu);
UpdateItemRequest uir = new UpdateItemRequest("users", pk, m);
dynamoDB.updateItem(uir);
One point of confusion is why the attribute value matters for a deletion. I really want to delete an attribute name and any associated values, but couldn't find the appropriate way to do that in the SDK.
Help would be appreciated.
I could have sworn I already tried this but by replacing the AttributeValue with a null value it works:
Key pk = new Key(new AttributeValue().withN(Long.toString(123)));
AttributeValueUpdate avu = new AttributeValueUpdate(null, "DELETE");
Map<String, AttributeValueUpdate> m = new HashMap<String, AttributeValueUpdate>();
m.put(String.valueOf(555), avu);
UpdateItemRequest uir = new UpdateItemRequest("users", pk, m);
dynamoDB.updateItem(uir);
This also works.
Table table = dynamoDB.getTable("users");
table.updateItem(new PrimaryKey("<MY HASH KEY NAME>", <MY HASH VALUE>), new AttributeUpdate("columnToRemove").delete());
or you can even use Expressions in an Item Update.
REMOVE - Removes one or more attributes from an item.
To delete an Attribute from Dynamo DB while Updating an item of the table
UpdateItemRequest updateItemRequest =new UpdateItemRequest().withTableName(tableName).withKey(key);
updateItemRequest.addAttributeUpdatesEntry("privileges",new AttributeValueUpdate()
.withAction(AttributeAction.DELETE));
updateItemRequest.addAttributeUpdatesEntry("description", new AttributeValueUpdate()
.withValue(new AttributeValue().withS("description")));
In above Example, First I removed privileges from Item and then updated description in Item.

How do I save a value into a custom field in JIRA programmatically?

I've spent days trying to find out how to save or update a value into a CustomField programmatically and finally found out how it's done. So I'll make this a question and then answer it as I would have loved to have this question and answer.
There is conflicting documentation on how to save or update a value for a Custom Field in JIRA. I was using:
customField.setCustomFieldValue(CustomField, value);
This does not save the value into the database but it does update the value as far as I can tell. It's only useful if you are using the CustomField further down in a Workflow Post Function transition for example.
I'm using Jira 4.3.2.
How do I persist the the CustomFields value into the JIRA database?
Ok, this is how I'm successfully updating and saving the CustomField value into the JIRA db.
Comments welcome...
private void saveValue(MutableIssue issue, String valueToSave, CustomField
customField) throws FieldLayoutStorageException {
issue.setCustomFieldValue(customField, valueToSave);
Map<String, ModifiedValue> modifiedFields = issue.getModifiedFields();
FieldLayoutItem fieldLayoutItem =
ComponentManager.getInstance().getFieldLayoutManager().getFieldLayout(issue).getFieldLayoutItem(
customField);
DefaultIssueChangeHolder issueChangeHolder = new DefaultIssueChangeHolder();
final ModifiedValue modifiedValue = (ModifiedValue) modifiedFields.get(customField.getId());
customField.updateValue(fieldLayoutItem, issue, modifiedValue, issueChangeHolder);
}
Here is how I do it (for a custom field I programmatically store a random UUID in):
CustomField cfHash = customFieldManager.getCustomFieldObjectByName(...);
IssueChangeHolder changeHolder = new DefaultIssueChangeHolder();
try {
Object newHashValue = java.util.UUID.randomUUID().toString();
Object oldHashValue = issue.getCustomFieldValue(cfHash);
issue.setCustomFieldValue(cfHash, newHashValue);
cfHash.updateValue(null, issue, new ModifiedValue(oldHashValue, newHashValue), changeHolder);
...
More or less the same as you but with another way to get the ModifiedValue-Object.
Here a solution that works for me in JIRA 6.4.7 to update a custom field value. Actually Im updating a single select field, therefore I have to get the Option for it:
MutableIssue issue = issueManager.getIssueByCurrentKey(issueKey);
FieldConfig relevantConfig = customField.getRelevantConfig(issue);
// if you use a text field use String. or double for numeric
Option optionForValue = optionsManager.getOptions(relevantConfig).getOptionForValue(option, null);
issue.setCustomFieldValue(customField,optionForValue);
Map<String, ModifiedValue> modifiedFields = issue.getModifiedFields();
FieldLayoutItem fieldLayoutItem =
fieldLayoutManager.getFieldLayout(issue).getFieldLayoutItem(customField);
DefaultIssueChangeHolder issueChangeHolder = new DefaultIssueChangeHolder();
final ModifiedValue modifiedValue = modifiedFields.get(customField.getId());
customField.updateValue(fieldLayoutItem, issue, modifiedValue, issueChangeHolder);
I had the same issue and had it resolved using this plugin, fyi=)

Categories

Resources