Retrieving data from Firebase (Realtime Database) into a list (Kotlin) - list

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

how to filter list object by using stream map filter in java

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()

LazyPagingItems not collecting for LazyVerticalGrid with Search Query Funtional Paging 3.0 Jetpack Compose

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 = {})
}
}
}
}
}

Swift: Finding an Object Property via regex

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 })

Parse JSON string to Model Object type Array

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)
}

MongoDB Map Reduce C#

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.