Right now I have a Firestore folder which contains numbered documents with information like Volume, temperature, air quality. These values are saved as numbers. I somehow want these Firestore numbers to be saved as Integer variables in my flutter project, so that I can work with them (For example show dark colors if the Volume is too loud).
But it just doesn't work, no matter what I try. Is it even possible? I can only display the firestore values, but I can't save them..
Here a picture of my database:
My code:
Future<String> getValue() async{
final doc = await FirebaseFirestore.instance
.collection('Digitaluhr')
.doc('1.002')
.get();
Future <String> lautstaerke = doc['Lautstärke'];
return lautstaerke;
}
#override
Widget build(BuildContext context) {
Future <String> Lautstaerke = getValue();
String transform = Lautstaerke.toString();
var test = int.parse(transform);
assert(test is int);
Text('$test'),
Output:
Please help :(
Check this out:
#override
Widget build(BuildContext context){
return FutureBuilder<String>(
future: getValue(),
builder: (_, snapshot){
if(snapshot.hasData){
var test = int.parse(snapshot.data);
...
}
return Container();
}
);
}
Posting LeonBrey's solution for visibility.
The problem was fixed with the following:
Luftguete = snapshot.data.docs[itemCount] ['Luftgüte'];
I think issue is doc['Lautstärke'] return string, while your variable data type is Future<String>
Future <String> lautstaerke = doc['Lautstärke'];
Try changing like below
String lautstaerke = doc['Lautstärke'];
Related
I need to get trending articles from the community. I created a apex class for that by using ConnectApi.Knowledge.getTrendingArticles(communityId, maxResult).
I need to create a test class for that. I am using test class method provided by Salesforce for that. setTestGetTrendingArticles(communityId, maxResults, result) but I am getting this error "System.AssertException: Assertion Failed: No matching test result found for Knowledge.getTrendingArticles(String communityId, Integer maxResults). Before calling this, call Knowledge.setTestGetTrendingArticles(String communityId, Integer maxResults, ConnectApi.KnowledgeArticleVersionCollection result) to set the expected test result."
public without sharing class ConnectTopicCatalogController {
#AuraEnabled(cacheable=true)
public static List<ConnectApi.KnowledgeArticleVersion> getAllTrendingArticles(){
string commId = [Select Id from Network where Name = 'Customer Community v5'].Id;
ConnectApi.KnowledgeArticleVersionCollection mtCollection = ConnectApi.Knowledge.getTrendingArticles(commId, 12);
System.debug('getAllTrendingTopics '+JSON.serializePretty(mtCollection.items));
List<ConnectApi.KnowledgeArticleVersion> topicList = new List<ConnectApi.KnowledgeArticleVersion>();
for(ConnectApi.KnowledgeArticleVersion mtopic : mtCollection.items)
{
topicList.add(mtopic);
}
return topicList;
}
}
Test class that I am using for this
public class ConnectTopicCatalogControllerTest {
public static final string communityId = [Select Id from Network where Name = 'Customer Community v5'].Id;
#isTest
static void getTrendingArticles(){
ConnectApi.KnowledgeArticleVersionCollection knowledgeResult = new ConnectApi.KnowledgeArticleVersionCollection();
List<ConnectApi.KnowledgeArticleVersion> know = new List<ConnectApi.KnowledgeArticleVersion>();
know.add(new ConnectApi.KnowledgeArticleVersion());
know.add(new ConnectApi.KnowledgeArticleVersion());
system.debug('know '+know);
knowledgeResult.items = know;
// Set the test data
ConnectApi.Knowledge.setTestGetTrendingArticles(null, 12, knowledgeResult);
List<ConnectApi.KnowledgeArticleVersion> res = ConnectTopicCatalogController.getAllTrendingArticles();
// The method returns the test page, which we know has two items in it.
Test.startTest();
System.assertEquals(12, res.size());
Test.stopTest();
}
}
I need help to solve the test class
Thanks.
Your controller expects the articles to be inside the 'Customer Community v5' community, but you are passing the communityId parameter as null to the setTestGetTrendingArticles method.
I am new to Flink and doing something very similar to the below link.
Cannot see message while sinking kafka stream and cannot see print message in flink 1.2
I am also trying to add JSONDeserializationSchema() as a deserializer for my Kafka input JSON message which is without a key.
But I found JSONDeserializationSchema() is not present.
Please let me know if I am doing anything wrong.
JSONDeserializationSchema was removed in Flink 1.8, after having been deprecated earlier.
The recommended approach is to write a deserializer that implements DeserializationSchema<T>. Here's an example, which I've copied from the Flink Operations Playground:
import org.apache.flink.api.common.serialization.DeserializationSchema;
import org.apache.flink.api.common.typeinfo.TypeInformation;
import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
/**
* A Kafka {#link DeserializationSchema} to deserialize {#link ClickEvent}s from JSON.
*
*/
public class ClickEventDeserializationSchema implements DeserializationSchema<ClickEvent> {
private static final long serialVersionUID = 1L;
private static final ObjectMapper objectMapper = new ObjectMapper();
#Override
public ClickEvent deserialize(byte[] message) throws IOException {
return objectMapper.readValue(message, ClickEvent.class);
}
#Override
public boolean isEndOfStream(ClickEvent nextElement) {
return false;
}
#Override
public TypeInformation<ClickEvent> getProducedType() {
return TypeInformation.of(ClickEvent.class);
}
}
For a Kafka producer you'll want to implement KafkaSerializationSchema<T>, and you'll find examples of that in that same project.
To solve the problem of reading non-key JSON messages from Kafka I used case class and JSON parser.
The following code makes a case class and parses the JSON field using play API.
import play.api.libs.json.JsValue
object CustomerModel {
def readElement(jsonElement: JsValue): Customer = {
val id = (jsonElement \ "id").get.toString().toInt
val name = (jsonElement \ "name").get.toString()
Customer(id,name)
}
case class Customer(id: Int, name: String)
}
def main(args: Array[String]): Unit = {
val env = StreamExecutionEnvironment.getExecutionEnvironment
val properties = new Properties()
properties.setProperty("bootstrap.servers", "xxx.xxx.0.114:9092")
properties.setProperty("group.id", "test-grp")
val consumer = new FlinkKafkaConsumer[String]("customer", new SimpleStringSchema(), properties)
val stream1 = env.addSource(consumer).rebalance
val stream2:DataStream[Customer]= stream1.map( str =>{Try(CustomerModel.readElement(Json.parse(str))).getOrElse(Customer(0,Try(CustomerModel.readElement(Json.parse(str))).toString))
})
stream2.print("stream2")
env.execute("This is Kafka+Flink")
}
The Try method lets you overcome the exception thrown while parsing the data
and returns the exception in one of the fields (if we want) or else it can just return the case class object with any given or default fields.
The sample output of the Code is:
stream2:1> Customer(1,"Thanh")
stream2:1> Customer(5,"Huy")
stream2:3> Customer(0,Failure(com.fasterxml.jackson.databind.JsonMappingException: No content to map due to end-of-input
at [Source: ; line: 1, column: 0]))
I am not sure if it is the best approach but it is working for me as of now.
This has baffled me for a while now and I cannot seem to get the grasp of it. I'm using Cell Value Factory to populate a simple one column table and it does not populate in the table.
It does and I click the rows that are populated but I do not see any values in them- in this case String values. [I just edited this to make it clearer]
I have a different project under which it works under the same kind of data model. What am I doing wrong?
Here's the code. The commented code at the end seems to work though. I've checked to see if the usual mistakes- creating a new column instance or a new tableview instance, are there. Nothing. Please help!
//Simple Data Model
Stock.java
public class Stock {
private SimpleStringProperty stockTicker;
public Stock(String stockTicker) {
this.stockTicker = new SimpleStringProperty(stockTicker);
}
public String getstockTicker() {
return stockTicker.get();
}
public void setstockTicker(String stockticker) {
stockTicker.set(stockticker);
}
}
//Controller class
MainGuiController.java
private ObservableList<Stock> data;
#FXML
private TableView<Stock> stockTableView;// = new TableView<>(data);
#FXML
private TableColumn<Stock, String> tickerCol;
private void setTickersToCol() {
try {
Statement stmt = conn.createStatement();//conn is defined and works
ResultSet rsltset = stmt.executeQuery("SELECT ticker FROM tickerlist order by ticker");
data = FXCollections.observableArrayList();
Stock stockInstance;
while (rsltset.next()) {
stockInstance = new Stock(rsltset.getString(1).toUpperCase());
data.add(stockInstance);
}
} catch (SQLException ex) {
Logger.getLogger(WriteToFile.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Connection Failed! Check output console");
}
tickerCol.setCellValueFactory(new PropertyValueFactory<Stock,String>("stockTicker"));
stockTableView.setItems(data);
}
/*THIS, ON THE OTHER HAND, WORKS*/
/*Callback<CellDataFeatures<Stock, String>, ObservableValue<String>> cellDataFeat =
new Callback<CellDataFeatures<Stock, String>, ObservableValue<String>>() {
#Override
public ObservableValue<String> call(CellDataFeatures<Stock, String> p) {
return new SimpleStringProperty(p.getValue().getstockTicker());
}
};*/
Suggested solution (use a Lambda, not a PropertyValueFactory)
Instead of:
aColumn.setCellValueFactory(new PropertyValueFactory<Appointment,LocalDate>("date"));
Write:
aColumn.setCellValueFactory(cellData -> cellData.getValue().dateProperty());
For more information, see this answer:
Java: setCellValuefactory; Lambda vs. PropertyValueFactory; advantages/disadvantages
Solution using PropertyValueFactory
The lambda solution outlined above is preferred, but if you wish to use PropertyValueFactory, this alternate solution provides information on that.
How to Fix It
The case of your getter and setter methods are wrong.
getstockTicker should be getStockTicker
setstockTicker should be setStockTicker
Some Background Information
Your PropertyValueFactory remains the same with:
new PropertyValueFactory<Stock,String>("stockTicker")
The naming convention will seem more obvious when you also add a property accessor to your Stock class:
public class Stock {
private SimpleStringProperty stockTicker;
public Stock(String stockTicker) {
this.stockTicker = new SimpleStringProperty(stockTicker);
}
public String getStockTicker() {
return stockTicker.get();
}
public void setStockTicker(String stockticker) {
stockTicker.set(stockticker);
}
public StringProperty stockTickerProperty() {
return stockTicker;
}
}
The PropertyValueFactory uses reflection to find the relevant accessors (these should be public). First, it will try to use the stockTickerProperty accessor and, if that is not present fall back to getters and setters. Providing a property accessor is recommended as then you will automatically enable your table to observe the property in the underlying model, dynamically updating its data as the underlying model changes.
put the Getter and Setter method in you data class for all the elements.
Earlier I had a table named ApplicationConfiguration which simply had [Key],[Value] columns to store some config data. This was queried straight away using SQL queries.
Now I intend to make use of Entity Framework (EF) Code First approach to query this table. The specialty of this table is that the table will have only a fixed number of rows in its lifetime. Only the Value column can be updated.
So as per the code first approach, we have to first write our POCO classes with its properties that will be mapped to columns in the underlying table. However, I wish to have a Dictionary<> structure to represent these configuration KV pairs. My concern is, will EF be able to fire update queries against any updation to the the value of a particular pair.
Also since I am using Code First approach, I would want some seed data(i.e the fixed number of rows and its initial content) to the added after the table itself is created on the fly when the application is first executed.
If Dictionary<> cannot be used, please suggest some alternative. Thanks in advance.
Coded this way:
public class ApplicationConfiguration
{
public int Id { get; set; }
public string Key { get; set; }
public int Value { get; set; } // should be string, but I'm lazy
}
class Context : DbContext
{
internal class ContextInitializer : DropCreateDatabaseIfModelChanges<Context>
{
protected override void Seed(Context context)
{
var defaults = new List<ApplicationConfiguration>
{
new ApplicationConfiguration {Key = "Top", Value = 5},
new ApplicationConfiguration {Key = "Bottom", Value = 7},
new ApplicationConfiguration {Key = "Left", Value = 1},
new ApplicationConfiguration {Key = "Right", Value = 3}
};
// foreach (var c in defaults)
// context.ConfigurationMap.Add(c.Key, c); // by design, no IReadOnlyDictionary.Add
foreach (var c in defaults)
context.ApplicationConfigurations.Add(c);
base.Seed(context);
}
}
public Context()
{
Database.SetInitializer(new ContextInitializer());
}
private IDbSet<ApplicationConfiguration> ApplicationConfigurations
{
get { return Set<ApplicationConfiguration>(); }
}
public IReadOnlyDictionary<string, ApplicationConfiguration> ConfigurationMap
{
get { return ApplicationConfigurations.ToDictionary(kvp => kvp.Key, kvp => kvp); }
}
}
Used this way:
using (var context = new Context())
{
ReadConfigurationOnly(context.ConfigurationMap);
}
using (var context = new Context())
{
ModifyConfiguration(context.ConfigurationMap);
context.SaveChanges();
}
static void ReadConfigurationOnly(IReadOnlyDictionary<string, ApplicationConfiguration> configuration)
{
foreach (var k in configuration.Keys)
Console.WriteLine("{0} = {1}", k, configuration[k].Value);
}
static void ModifyConfiguration(IReadOnlyDictionary<string, ApplicationConfiguration> configuration)
{
foreach (var k in configuration.Keys)
configuration[k].Value++; // this is why I was lazy, using an int for a string
}
So, I wrote it up this way — using an int Value property rather than a string — just so I could run the "Used this way" code over and over, and see the database update each time, without having to come up with some other way to change Value in an interesting way.
It's not quite as nifty here to use a IReadOnlyDictionary<string, ApplicatonConfiguration> instead of a IReadOnlyDictionary<string, string>, the way we'd really like, but that's more than made up for by the fact that we can easily modify our collection values without resorting to a clumsier Set method taking a dictionary as input. The drawback, of course, is that we have to settle for configuration[key].Value = "new value" rather than configuration[key] = "new value", but — as I say — I think it's worth it.
EDIT
Dang! I wrote this code up specifically to answer this question, but I think I like it so much, I'm going to add it to my bag of tricks ... this would fit in really well when my company goes from local databases to Azure instances in the cloud, and the current app.config has to go into the database.
Now all I need is a ContextInitializer taking a System.Configuration.ConfigurationManager as a ctor parameter in order to seed a new database from an existing app.config ...
I don't think you can map a table directly to a Dictionary; you will probably have to write your own wrapper to fill a dictionary from the table and update it back to the DB. Entities are each a row of a given table... Something like this (untested):
public Dictionary<string, string> GetDictionary()
{
Dictionary<string, string> dic = new Dictionary<string, string>();
using (var db = new Context())
{
var configs = db.ApplicationConfiguration.Select();
foreach (var entry in configs)
{
dic.Add(config.Key, config.Value);
}
}
return dic;
}
public void SaveConfig(Dictionary<string, string> dic)
{
using (var db = new Context())
{
foreach (KeyValuePair kvp in dic)
{
if (!db.ApplicationConfiguration.First(a => a.Key == kvp.Key).Value == kvp.Value)
{
var ac = new ApplicationConfiguration();
ac.Key = kvp.Key;
ac.Value = kvp.Value;
db.Entry(ac).State = EntityState.Modified;
}
}
db.SaveChanges();
}
}
For your second question, you want to use the Seed() method to add initial values to the database. See here for an example implementation.
I have created a document in ravendb. Using session.advanced.getmetadata(see in code) , i gave a name to Raven-Entity-Name in metadata, after that i deleted that document in same function.Then i saw collection is also removed.If i delete the document manually from raven studio then the collection remains in the database.How a collection persist even if there is no document from code part? thanks in advance !!
My c# code is :
public CreateCollectionResult CreateCollection(string databaseName, string collectionName)
{
CreateCollectionResult createCollectionResult = new CreateCollectionResult();
Collection collection1234 = new Collection();
try
{
using (var session = documentStore.OpenSession(databaseName))
{
Guid guid = new Guid("12345678-1111-1111-2222-000000000000");
session.Store(collection1234, guid, "april-Days/10");
session.Advanced.GetMetadataFor<Collection>(collection1234)[Constants.RavenEntityName] = collectionName;
//session.Delete<Collection>(collection1234);
session.SaveChanges();
createCollectionResult.IsOperationSuccessfull = true;
}
}
//exception if database not found
catch (InvalidOperationException ex)
{
createCollectionResult.IsOperationSuccessfull = false;
createCollectionResult.Error = ex;
}
return createCollectionResult;
}
In RavenDB, collections are virtual, they are only there as long as you have at least one doc in that document.