The RealtimeDatabase structure in Firebase
I want to go over the entire users in "mifkada" and to add them into a list as a BlogPost object:
class BlogPost (
var namerv: String,
var gafrv: String,
var placerv: String,
var phonerv: String,
var notesrv: String
) {
constructor() : this("", "", "", "", "") {}
}
I tried to do it with a for loop but it doesn't work the way I wrote it
class DataSource{
companion object{
fun createDataSet(): ArrayList<BlogPost>{
var databaseMifkada = FirebaseDatabase.getInstance().getReference("mifkada")
val list = ArrayList<BlogPost>()
val postListener = object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
if(dataSnapshot!!.exists()){
list.clear()
for (e in dataSnapshot.children){
val post = e.getValue(BlogPost::class.java)
list.add(post!!)
}
}
}
override fun onCancelled(databaseError: DatabaseError) {
// Getting Post failed, log a message
Log.w(TAG, "loadPost:onCancelled", databaseError.toException())
}
}
databaseMifkada.addValueEventListener(postListener)
return list
}
}
}
The values of your constructor does not match the names of your database values
class BlogPost (
var namerv: String,
var gafrv: String,
var placerv: String,
var phonerv: String,
var notesrv: String
) {
constructor() : this("", "", "", "", "") {}
}
Should be
class BlogPost (
var name: String,
var gaf: String,
var place: String,
var phone: String,
var notes: String
) {
constructor() : this("", "", "", "", "") {}
}
You need to have the same name because when you do
val post = e.getValue(BlogPost::class.java)
it will look for those field names under the reference, and if it can't be reached, you can't get those values
Related
i want to filter a list of student in java. I have a student class in kotlin like this.
class Student(
var id: String? = null,
var firstName: String? = null,
var lastName: String? = null
) {
constructor(entity: StudentCourse?): this() {
if (entity != null) {
this.id = entity.id.id
this.name = entity.name
}
}
}
class StudentCourse (#EmbeddedId open var id: StudentCourseId) {
constructor() : this(StudentCourseId())
open var name: Boolean? = null
}
#Embeddable
open class StudentCourseId: Serializable {
open var id: String? = null
open var deptName: String? = null
}
this is the list i want to filter :
var students: List<Student> = listOf(
Student("14adbv45", "dan", "GEG"),
Student("96adbv42","Bob", "Bowyer"),
Student("30adbv45","Emily", "Eden")
)
I do this
List<students> studentListContainsFirstNameBob = students.stream()
.map(StudentCourse)
.filter(e -> e.getFirstName.equals("Bob"))
.flatMap(List::stream);
but it doesn't work.
How can i do it please
There are multiple issues in your code.
For example in this part:
constructor(entity: StudentCourse?): this() {
if (entity != null) {
this.id = entity.id.id
this.name = entity.name
}
}
The entity.name refers to StudentCourse#name, but this property is actually of Boolean type, so comparing it to String doe snot make much sense. You have also doubled .id which is incorrect.
Next thing, I am not sure what this snipped should do, was the intention to link a student with given course? If so, you would probably like to add a list of students to a course, or a list of courses to a student (which sounds more correct).
Finally, when it comes to filtering a list, you can get students with first name Bob in this way:
var studentListContainsFirstNameBob: List<Student> = students
.filter { it.firstName.equals("Bob") }
.toList()
Mind the it variable refers to the element from the list, it could also be written:
var studentListContainsFirstNameBob: List<Student> = students
.filter { student -> student.firstName.equals("Bob") }
.toList()
I want to update list from paging with search query result,basically I had success to display item paging to lazyverticalgrid without searchQuery variable. The problem is when I click search button from keyboard virtual, the items not update in compose
HomeViewModel.kt
#HiltViewModel
class HomeViewModel #Inject constructor(
savedStateHandle: SavedStateHandle,
private val productRepository: ProductRepository,
private val dataUserDao: DataUserDao
) : ViewModel() {
private val _searchLiveData = savedStateHandle.getLiveData("search", "")
val searchLiveData: LiveData<String> get() = _searchLiveData
private val _productList = MutableStateFlow<PagingData<Product>>(PagingData.empty())
val productList = _productList.asStateFlow()
init {
getDashboard()
getBanner()
searchProduct("") // this work!
}
fun searchProduct(s: String) { // when this execute again with value the product list not recomposed
viewModelScope.launch {
productRepository.getProducts(0, s, "", "").collect { data ->
_productList.value = data
}
}
}
The collectAsLazyPagingItems function for product list is work when search query is empty, but when search query is not empty collectAsLazyPagingItems function is not triggered
ShopScreen.kt
#HomeNavGraph
#Destination
#Composable
fun ShopScreen(
navigator: DestinationsNavigator,
viewModel: HomeViewModel = hiltViewModel()
) {
.....
val lazyGridState = rememberLazyGridState(
val productListItems: LazyPagingItems<Product> =
viewModel.productList.collectAsLazyPagingItems()
Column(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 16.dp)
) {
...
LazyVerticalGrid(
state = lazyGridState,
columns = GridCells.Adaptive(screenWidth),
verticalArrangement = Arrangement.spacedBy(10.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp),
contentPadding = PaddingValues(vertical = 16.dp)
) {
Log.e("TAG", "ShopScreen: ${state.productList.size}")
items(productListItems.itemCount) { index ->
CardProductShopGrid(product = productListItems[index]!!, onClick = {})
}
}
}
}
}
Target: The following function shall iterate over an array of objects and check a specific property of all objects. This property is a string and shall be matched with a user input via regex. If there's a match the object shall be added to an array which will further be passed to another function.
Problem: I don't know how to set up regex in Swift 3. I'm rather new in Swift at all, so an easily understandable solution would be very helpful :)
How it currently looks like:
func searchItems() -> [Item] {
var matches: [Item] = []
if let input = readLine() {
for item in Storage.storage.items { //items is a list of objects
if let query = //regex with query and item.name goes here {
matches.append(item)
}
}
return matches
} else {
print("Please type in what you're looking for.")
return searchItems()
}
}
This is what Item looks like (snippet):
class Item: CustomStringConvertible {
var name: String = ""
var amount: Int = 0
var price: Float = 0.00
var tags: [String] = []
var description: String {
if self.amount > 0 {
return "\(self.name) (\(self.amount) pcs. in storage) - \(price) €"
} else {
return "\(self.name) (SOLD OUT!!!) - \(price) €"
}
}
init(name: String, price: Float, amount: Int = 0) {
self.name = name
self.price = price
self.amount = amount
}
}
extension Item: Equatable {
static func ==(lhs: Item, rhs: Item) -> Bool {
return lhs.name == rhs.name
}
}
Solved. I just edited this post to get a badge :D
For the purpose of letting the answer to be generic and clear, I will assume that the Item model is:
struct Item {
var email = ""
}
Consider that the output should be a filtered array of items that contains items with only valid email.
For such a functionality, you should use NSRegularExpression:
The NSRegularExpression class is used to represent and apply regular
expressions to Unicode strings. An instance of this class is an
immutable representation of a compiled regular expression pattern and
various option flags.
According to the following function:
func isMatches(_ regex: String, _ string: String) -> Bool {
do {
let regex = try NSRegularExpression(pattern: regex)
let matches = regex.matches(in: string, range: NSRange(location: 0, length: string.characters.count))
return matches.count != 0
} catch {
print("Something went wrong! Error: \(error.localizedDescription)")
}
return false
}
You can decide if the given string does matches the given regex.
Back to the example, consider that you have the following array of Item Model:
let items = [Item(email: "invalid email"),
Item(email: "email#email.com"),
Item(email: "Hello!"),
Item(email: "example#example.net")]
You can get the filtered array by using filter(_:) method:
Returns an array containing, in order, the elements of the sequence
that satisfy the given predicate.
as follows:
let emailRegex = "[A-Z0-9a-z._%+-]+#[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"
let emailItems = items.filter {
isMatches(emailRegex, $0.email)
}
print(emailItems) // [Item(email: "email#email.com"), Item(email: "example#example.net")]
Hope this helped.
You can do the same with filter function
let matches = Storage.storage.items.filter({ $0.yourStringPropertyHere == input })
I got Encrypted data from API hit by below method
URLSession.shared.dataTask(with: url!)
converted data into JSON but still it is encrypted
var json = try(JSONSerialization.jsonObject(with: data!, options: .allowFragments))
converted it into string
let arr:String = json as! String
decrypted it
let jsonText = arr.fromBase64()//extension method, given end of question
now it is in Json Formate as below (this is only 1 record, there are more than 1 records in Json string)
{
"CompanyAlt_Key": 1,
"Company_Name": "XYZ LTD",
"TableName": "CompanyList"
},
I have a model of same type
public class CompanyList {
public var companyAlt_Key : Int?
public var company_Name : String?
public var tableName : String?
}
here is fromBase64 method
func fromBase64() -> String {
let data = NSData.init(base64Encoded: self, options: []) ?? NSData()
return String(data: data as Data, encoding: String.Encoding.utf8) ?? ""
}
I am facing problem to get the Json String into an array of type CompanyList class
Help would be appreciate
You'll need to convert your jsonString to data first:
let jsonData = jsonString.data(using: .utf8)!
The convert the data to an array
let array = JSONSerialization.jsonObject(with: jsonData, options: nil) as? [[String: Any]]
Then iterate through the array…
let companies = array?.map {
return CompanyList(dictionary: $0)
}
Implement an init method for your CompanyList, passing in a dictionary for each record in your response…
public class CompanyList {
public var companyAlt_Key : Int?
public var company_Name : String?
public var tableName : String?
init(dictionary: [String: Any]) {
companyAlt_Key = dictionary["companyAlt_Key"] as? Int
company_Name = dictionary["company_Name"] as? String
tableName = dictionary["tableName"] as? String
}
}
You can also use this to validate the data. If the fields in your class are non-optional, you can use an optional init as follows…
public class CompanyList {
public var companyAlt_Key : Int
public var company_Name : String
public var tableName : String
init?(dictionary: [String: Any]) {
guard let companyAlt_Key = dictionary["companyAlt_Key"] as? Int,
let company_Name = dictionary["company_Name"] as? String,
let tableName = dictionary["tableName"] as? String else {
return nil
}
self.companyAlt_Key = companyAlt_Key
self.company_Name = company_Name
self.tableName = tableName
}
}
If you're using an optional init, use flatMap to ensure you don't have any optional elements in your array…
let companies = array?.flatMap {
return CompanyList(dictionary: $0)
}
I am currently doing a map-reduce with the c# driver in Mongo.
I have got it working where the JSON is as follows:
{ "_id" : CSUUID("ef53b163-699c-462f-9135-b81bad115635"), "value" : { "firstname" : "Joe", "lastname" : "Bloggs", "groupName" : "System Wide Access" } }
What I want to do is flatten this object so as I don't have an Id and Value field, I only want the actual properties that are in my read model class.
Here is my code as it is currently:
const string mapUserGroupMember = #"function ()
{
var output = {groupId:this.GroupId, firstname:this.Forename, lastname:this.Surname, groupName:null}
emit(this.GroupId, output);
}";
const string mapUserGroupName = #"function ()
{
var output = {groupId:this._id, firstname:null, lastname:null, groupName:this.Name}
emit(this._id, output);
}";
var reduceF = #"function(key, values) {
var results = {firstname:null, lastname:null , groupName:null};
values.forEach(function(v){
if(results.firstname ==null){
results.firstname = v.firstname
}
if(results.lastname ==null){
results.lastname = v.lastname
}
if(results.groupName ==null){
results.groupName = v.groupName
}
});
return results;
};";
var groupMemberCollection = database.GetCollection("UserGroupMemberReadModel");
var groupNameCollection = database.GetCollection("UserGroupNameReadModel");
var options = new MapReduceOptionsBuilder();
options.SetOutput(MapReduceOutput.Reduce("MergedData"));
var results = groupNameCollection.MapReduce(mapUserGroupName, reduceF, options);
results = groupMemberCollection.MapReduce(mapUserGroupMember, reduceF, options);
I want to be able to call var collection = database.GetCollection("MergedData").AsQueryable<ReadModel>();
Any help would be appreciated.