Checking if username already exists gives error kotlin - firebase

I translated the code below from java, but I am getting an error in some places, why is it giving an error, is there a point I missed?
val mQuery: Query = firestore.collection("users")
.whereEqualTo("nickname", mUserName)
mQuery.addSnapshotListener(object : EventListener<QuerySnapshot> {
fun onEvent(
documentSnapshots: QuerySnapshot,
e: FirebaseFirestoreException?
) {
for (ds in documentSnapshots) {
if (ds != null) {
val userName: String = document.getString("username")
Log.d(
TAG,
"checkingIfusernameExist: FOUND A MATCH: $userName"
)
Toast.makeText(
this#SignUpActivity,
"That username already exists.",
Toast.LENGTH_SHORT
).show()
}
}
}
})
I've been doing the things described here for 2-3 days, but it keeps throwing an error.Event listeners and docs throw errors.

I translated the code below from java
That's not the correct way of "translating" that code from Java to Kotlin, since that answer provides a solution for getting data only once. So to be able to do that in Kolin programming language please use the following lines of code:
val rootRef = FirebaseFirestore.getInstance()
val allUsersRef = rootRef.collection("all_users")
val userNameQuery = allUsersRef.whereEqualTo("username", "userNameToCompare")
userNameQuery.get().addOnCompleteListener { task ->
if (task.isSuccessful) {
for (document in task.result) {
if (document.exists()) {
Log.d("TAG", "username already exists")
val userName = document.getString("username")
//Do what you need to do with the userName
} else {
Log.d("TAG", "username does not exists")
}
}
} else {
Log.d("TAG", "Error getting documents: ", task.exception)
}
}

Related

How do i make my code in kotlin read data from the firebase firestore

I am trying to make an app that reads data from the firebase firestore and then shows in a screen that same data
The problem the data only appears when shown in log but i want the in text(string)
Can anyone help me understand how to do it
I already tried many videos explaining but none of then work so my last option is really ask in here for help.
Here is the code
#SuppressLint("UnrememberedMutableState")
#Composable
fun DB () {
val db = Firebase.firestore
val collectionReference = db.collection("Inventário")
.document("Bloco E")
.collection("Sala E0.05")
val data = mutableStateOf(mapOf<String, Any>())
val job = remember { Job() }
remember {
GlobalScope.launch(Dispatchers.Main) {
val documentSnapshot = collectionReference.document("Computador").get().await()
try {
data.value = documentSnapshot.data ?: mapOf()
}catch (e: Exception){
Log.e("Firestore", "Error retrieving data", e)
}
}
}
Column() {
data.value.forEach { (key, value) ->
Text("$key: $value")}
}
}
And here is the database structure:
It seems like you forgot to use remember on your MutableState (and also suppressed the lint warning with (#SuppressLint("UnrememberedMutableState"))):
val (data, setData) = remember { mutableStateOf(mapOf<String, Any>()) }
Also, using GlobalScope in Android is not recommended. Consider using a LaunchedEffect instead:
#Composable
fun DB () {
val db = Firebase.firestore
val collectionReference = db.collection("Inventário")
.document("Bloco E")
.collection("Sala E0.05")
val (data, setData) = remember { mutableStateOf(mapOf<String, Any>()) }
LaunchedEffect(collectionReference) {
try {
val documentSnapshot = collectionReference.document("Computador").get().await()
setData(documentSnapshot.data ?: mapOf())
} catch (e: Exception) {
Log.e("Firestore", "Error retrieving data", e)
}
}
Column() {
data.value.forEach { (key, value) ->
Text("$key: $value")}
}
}

Error while performing compound queries in firestore

I want to perform a compound query in firestore where I would like to get all documents with field bloodgroup equal to A+ and with field createdBy not equal to email. This email is that of the logged in user. When I perform the query I get NullPointerException. How to perform the query correctly 021-07-24 19:50:24.746 17550-17550/com.example.bloodbankcompany E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.bloodbankcompany, PID: 17550 java.lang.NullPointerExceptionatcom.example.bloodbankcompany.UserlistActivity$EventChangeListener3$1.onEvent(UserlistActivity.kt:217) I am storing the document snapshot inside the userArrayList array. Without the whereNotEqualTo query I am getting output where my documents get listed in recyclerview.
private fun EventChangeListener2(){
val sharedPreferences1 = getSharedPreferences("email", Context.MODE_PRIVATE)
val email: String? = sharedPreferences1.getString("email","null")?.trim()
Toast.makeText(this, "ssrae$email", Toast.LENGTH_SHORT ).show()
mFireStore.collection("applicationForm").whereNotEqualTo("createdBy",email).whereEqualTo("bloodgroup","A+").addSnapshotListener(object : EventListener<QuerySnapshot>{
override fun onEvent(value: QuerySnapshot?, error: FirebaseFirestoreException?) {
if (error!= null){
Log.e("firestore error", error.message.toString())
}
for(dc: DocumentChange in value?.documentChanges!!){
if (dc.type== DocumentChange.Type.ADDED){
userArrayList.add(dc.document.toObject(User1::class.java))
var number=userArrayList
var number1 =userArrayList
}
// Toast.makeText(applicationContext,userArrayList.toString(), Toast.LENGTH_SHORT).show()
}
myAdapter.notifyDataSetChanged()
}
})
}
Well, I have edited a little bit of your code, if it still doesn't work add a comment.
Also, an explanation about changes is commented below.
private fun EventChangeListener2() {
val sharedPreferences1 = getSharedPreferences("email", Context.MODE_PRIVATE)
val email: String? = sharedPreferences1.getString("email", "null")?.trim()
Log.d("firestore email", email.toString())
Toast.makeText(this, "ssrae$email", Toast.LENGTH_SHORT).show()
// try and catch will avoid your app to crash.
try {
//ref
var ref = mFireStore.collection("applicationForm")
.whereEqualTo("bloodgroup", "A+")
/**
* I believe since your email is of type nullable and there may be
* maybe a chance that email is null and is given to whereNotEqualTo
* I am just making an assumption here since I don't know what you
* recieve from sharedPreferences and whether it is null or not
*
* So, what I have done here is,
* firstly, I have split the firestore call into 2 parts and
* Secondly, I have a null-check for email, if it is
* not-null ref will also include this query
*
*/
//null Check for email
if (email != null) ref = ref.whereNotEqualTo("createdBy", email)
// Snapshot Listener
ref.addSnapshotListener(object : EventListener<QuerySnapshot> {
override fun onEvent(value: QuerySnapshot?, error: FirebaseFirestoreException?) {
if (error != null) {
Log.e("firestore error", error.message.toString())
}
for (dc: DocumentChange in value?.documentChanges!!) {
if (dc.type == DocumentChange.Type.ADDED) {
userArrayList.add(dc.document.toObject(User1::class.java))
var number = userArrayList
var number1 = userArrayList
}
// Toast.makeText(applicationContext,userArrayList.toString(), Toast.LENGTH_SHORT).show()
}
myAdapter.notifyDataSetChanged()
}
})
} catch (e: Exception) {
Log.e("firestore error", "Error", e)
}
}
EDIT:
According to firebase docs,
https://firebase.google.com/docs/firestore/query-data/indexing#exemptions
If you attempt a compound query with a range clause that doesn't map to an existing index, you receive an error. The error message includes a direct link to create the missing index in the Firebase console.

SQLite SQLITE_MISUSE error in Swift 3

I´m trying to create a function that injects queries to SQLite in Swift 3 but I´m having problems with the escaping chars
class SQLiteQueryManager {
static func insertNewStore(StoreId: Int64, Name: String, Address: String) -> Bool {
let vCommand = "INSERT INTO Store (Id, StoreId, Name, Address) VALUES (\(SQLiteConnectionManager.nextID("Store")),\(StoreId),'\(Name)','\(Address)')"
return SQLiteConnectionManager.insertDatabase(vCommand)
}
}
The problem ins that when I´m trying to execute SQLiteConnectionManager.insertDatabase function the string that I´m sending to SQLite looks like this:
INSERT INTO Store (Id, StoreId, Name, Address) VALUES (1,1,\'Tienda
1\',\'Dirección 1\')
And SQLite is rejecting the query.
I have tried .replacingOccurrences(of: "\", with: "") but it dose not work.
I have tested in DB Browser the query and works
INSERT INTO Store (Id, StoreId, Name, Address) VALUES (1,1,'Tienda
1','Dirección 1')
How can I remove the \??
My SQLite function is this:
static func insertDatabase(_ pCommand: String) -> Bool
{
var vInsertStatement: OpaquePointer? = nil
let vDB: OpaquePointer = SQLiteConnectionManager.openDatabase()
var vReturn: Bool
if sqlite3_prepare_v2(vDB, pCommand.replacingOccurrences(of: "\\", with: ""), -1, &vInsertStatement, nil) == SQLITE_OK {
if sqlite3_step(vInsertStatement) == SQLITE_DONE {
print("insertDatabase() correct with statement \(pCommand)")
vReturn = true
} else {
print("insertDatabase() fail with statement \(pCommand)")
vReturn = false
}
} else {
print("insertDatabase() pCommand could not be prepared")
vReturn = false
}
sqlite3_finalize(vInsertStatement)
sqlite3_close(vDB)
return vReturn
}
The Open function return ok so my guess is the escaping char or something like that.
This is the print output of the function:
insertDatabase() fail with statement INSERT INTO Store (Id, StoreId,
Name, Address) VALUES (1,1,'Tienda 1','Dirección 1')
UPDATE 1:
sqlite3_step(vInsertStatement) is returning SQLITE_MISUSE but I can't find the mistake, the DB is in the bundle and the open() statement work and a select I'm doing works, what can be wrong?
UPDATE 2:
This is how I open de DB and returns OK:
private static func openDatabase() -> OpaquePointer {
var vDB: OpaquePointer? = nil
mDBURL = Bundle.main.url(forResource: "ARDB", withExtension: "db")
if let vDBURL = mDBURL{
if sqlite3_open(vDBURL.absoluteString, &vDB) == SQLITE_OK {
print("The database is open.")
} else {
print("Unable to open database in method openDatabase().")
}
return vDB!
} else {
return vDB!
}
}
Then I run this to get the last Id and works:
static func nextID(_ pTableName: String!) -> Int
{
var vGetIdStatement: OpaquePointer? = nil
let vDB: OpaquePointer = SQLiteConnectionManager.openDatabase()
let vCommand = String(format: "SELECT Id FROM %# ORDER BY Id DESC LIMIT 1", pTableName)
var vResult: Int32? = 0
if sqlite3_prepare_v2(vDB, vCommand, -1, &vGetIdStatement, nil) == SQLITE_OK {
if sqlite3_step(vGetIdStatement) == SQLITE_ROW {
vResult = sqlite3_column_int(vGetIdStatement, 0)
print("nextID() correct with statement \(vCommand)")
} else {
print("nextID() fail with statement \(vCommand)")
}
} else {
print("nextID() statement could not be prepared")
}
sqlite3_finalize(vGetIdStatement)
sqlite3_close(vDB)
var id: Int = 1
if (vResult != nil)
{
id = Int(vResult!) + 1
}
return id
}
I have change my insert function to this with or without cString statement:
static func insertDatabase(_ pCommand: String) -> Bool
{
var vInsertStatement: OpaquePointer? = nil
let vDB: OpaquePointer = SQLiteConnectionManager.openDatabase()
var vReturn: Bool
if sqlite3_prepare_v2(vDB, pCommand.cString(using: .utf8), -1, &vInsertStatement, nil) == SQLITE_OK {
if sqlite3_step(vInsertStatement) == SQLITE_DONE {
print("insertDatabase() correct with statement \(pCommand)")
vReturn = true
} else {
print("insertDatabase() fail with statement \(pCommand) with error: \(sqlite3_step(vInsertStatement)) : \(sqlite3_errmsg(vDB))")
vReturn = false
}
} else {
print("insertDatabase() \(pCommand) could not be prepared with error: \(sqlite3_prepare_v2(vDB, pCommand.cString(using: .utf8), -1, &vInsertStatement, nil))")
vReturn = false
}
sqlite3_finalize(vInsertStatement)
sqlite3_close(vDB)
return vReturn
}
If I print the sqlite3_errmsg(vDB) in the console I get this that does not help:
▿ Optional> ▿ some : 0x0000000105347e80
- pointerValue : 4382293632
If I print sqlite3_step(vInsertStatement) returns 21 SQLITE_MISUSE
Any help will be appreciated.
Thanks in advance.
I just found the problem, we don´t have permission of writing in the main bundle.
So you have to copy the DB first, here is the code:
private static func copyFromBundle () {
let vBundlePath = Bundle.main.path(forResource: "ARDB", ofType: ".db")
let vDestPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
let vFileManager = FileManager.default
let vFullDestPath = URL(fileURLWithPath: vDestPath).appendingPathComponent("ARDB.db")
mDocumentsPath = ""
if vFileManager.fileExists(atPath: vFullDestPath.path){
print("Database file exist don´t copy.")
mDocumentsPath = vFullDestPath.path
} else {
if vFileManager.fileExists(atPath: vBundlePath!) {
do {
try vFileManager.copyItem(atPath: vBundlePath!, toPath: vFullDestPath.path)
print("Database file does´t exist copy it.")
mDocumentsPath = vFullDestPath.path
} catch {
print("copyFromBundle() fail with error: ",error)
}
}
}
}
Thanks for the help.
Happy coding.

Access one to many CoreData with predicate

I have an one-to-many database (Questions--->>Buttons)
I am stuck here as I don't know how to proceed with this to access the buttons from my database:
I have the following code that I can get to my Questions Entity but I don't know how to proceed from here. Thanks
func presentQuestionDetails(questionID :Int) {
let coreDataStack = CoreDataStack()
managedObjectContext = coreDataStack.persistentContainer.viewContext
let fetchRequest: NSFetchRequest<Questions> = Questions.fetchRequest()
let myPredicate = NSPredicate(format: "%K == %i", "questionID", questionID)
fetchRequest.predicate = myPredicate
do {
let results = try managedObjectContext!.fetch(fetchRequest)
if results.isEmpty {
//empty
print("empty")
}
else {
let question = results[0]
//do something
print("got something")
questionLabel.text = question.questionTitle
for _ in 0..<(question.buttons?.count)! {
//I'D LIKE TO LOOP THROUGH MY BUTTONS HERE AND ACCESS MY "buttonTitle" i.e print(buttons.buttonTitle!)
}
}
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
Would that be the correct way? I am only guessing and would like your input.
It seems to provide the right outcome but I am not sure if this is the right way to do it...
thanks
[...]
else {
let question = results[0]
//do something
print("got something")
questionLabel.text = question.questionTitle
let fetchRequest: NSFetchRequest<Buttons> = Buttons.fetchRequest()
let myPredicate = NSPredicate(format: "%K == %i", "questions", questionID)
fetchRequest.predicate = myPredicate
do {
let results = try managedObjectContext!.fetch(fetchRequest)
for buttons in results {
print(buttons.buttonTitle!)
}
}
catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}

Fixed a bug that KAA-1594: error after attaching endpoint to user

The bug in kaa 0.10 have Influenced my application development. So I try to fix it.Then I Compared the code of the kaa 0.9 and kaa 0.10. I have found the differences in class EndpointServiceImpl of Kaa DAO interface modular:there are two methods of attachEndpointToUser in it
1,
public EndpointProfileDto attachEndpointToUser(String endpointUserId, String
endpointAccessToken) throws KaaOptimisticLockingFailureException {
LOG.info("Try to attach endpoint with access token {} to user with {}", endpointAccessToken,
endpointUserId);
validateString(endpointUserId, "Incorrect endpointUserId "
+ endpointUserId);
EndpointUser endpointUser = endpointUserDao.findById(endpointUserId);
LOG.trace("[{}] Found endpoint user with id {} ", endpointUserId, endpointUser);
if (endpointUser
!= null) {
EndpointProfile endpoint = endpointProfileDao.findByAccessToken(endpointAccessToken);
LOG.trace("[{}] Found endpoint profile by with access token {} ", endpointAccessToken,
endpoint);
if (endpoint
!= null) {
if (endpoint.getEndpointUserId()
== null
|| endpointUserId.equals(endpoint.getEndpointUserId())) {
LOG.debug("Attach endpoint profile with id {} to endpoint user with id {} ", endpoint
.getId(), endpointUser.getId());
List<String> endpointIds = endpointUser.getEndpointIds();
**/*if (endpointIds
!= null
&& endpointIds.contains(endpoint.getId())) {
LOG.warn("Endpoint is already assigned to current user {}.", endpoint
.getEndpointUserId());
return getDto(endpoint);
}*/**
if (endpointIds
== null) {
endpointIds = new ArrayList<>();
endpointUser.setEndpointIds(endpointIds);
}
endpointIds.add(endpoint.getId());
endpointUser = endpointUserDao.save(endpointUser);
while (true) {
try {
endpoint.setEndpointUserId(endpointUser.getId());
LOG.trace("Save endpoint user {} and endpoint profile {}", endpointUser, endpoint);
endpoint = endpointProfileDao.save(endpoint);
break;
} catch (KaaOptimisticLockingFailureException ex) {
LOG.warn("Optimistic lock detected in endpoint profile ", Arrays.toString(endpoint
.getEndpointKey()), ex);
endpoint = endpointProfileDao.findByKeyHash(Sha1HashUtils.hashToBytes(endpoint
.getEndpointKey()));
}
}
return getDto(endpoint);
} else {
LOG.warn("Endpoint is already assigned to different user {}. Unassign it first!.",
endpoint.getEndpointUserId());
throw new DatabaseProcessingException("Endpoint is already assigned to different user.");
}
} else {
LOG.warn("Endpoint with accessToken {} is not present in db.", endpointAccessToken);
throw new DatabaseProcessingException("No endpoint found for specified accessToken.");
}
} else {
LOG.warn("Endpoint user with id {} is not present in db.", endpointUserId);
throw new DatabaseProcessingException("Endpoint user is not present in db.");
}
}
2,
public EndpointProfileDto attachEndpointToUser(String userExternalId, String tenantId,
EndpointProfileDto profile) {
validateString(userExternalId, "Incorrect userExternalId "
+ userExternalId);
EndpointUser endpointUser = endpointUserDao.findByExternalIdAndTenantId(userExternalId,
tenantId);
if (endpointUser
== null) {
LOG.info("Creating new endpoint user with external id: [{}] in context of [{}] tenant",
userExternalId, tenantId);
EndpointUserDto endpointUserDto = new EndpointUserDto();
endpointUserDto.setTenantId(tenantId);
endpointUserDto.setExternalId(userExternalId);
endpointUserDto.setUsername(userExternalId);
endpointUser = endpointUserDao.save(endpointUserDto);
}
List<String> endpointIds = endpointUser.getEndpointIds();
if (endpointIds
== null) {
endpointIds = new ArrayList<>();
endpointUser.setEndpointIds(endpointIds);
} **/*else if (endpointIds
!= null
&& endpointIds.contains(profile.getId())) {
LOG.warn("Endpoint is already assigned to current user {}.", profile.getEndpointUserId());
return profile;
}*/**
endpointIds.add(profile.getId());
endpointUser = endpointUserDao.save(endpointUser);
profile.setEndpointUserId(endpointUser.getId());
while (true) {
try {
LOG.trace("Save endpoint user {} and endpoint profile {}", endpointUser, profile);
return saveEndpointProfile(profile);
} catch (KaaOptimisticLockingFailureException ex) {
LOG.warn("Optimistic lock detected in endpoint profile ", Arrays.toString(profile
.getEndpointKey()), ex);
profile = findEndpointProfileByKeyHash(profile.getEndpointKeyHash());
profile.setEndpointUserId(endpointUser.getId());
}
}
}
The code above is in kaa 0.10 .Compared with the Kaa 0.9, it Added a judgment condition that in Bold code above:(
if(endpointIds!=null&&endpointIds.contains(endpoint.getId())) )
and
else if (endpointIds
!= null
&& endpointIds.contains(profile.getId())).
I have made a test that Commented the judgment condition codes. The result is OK. I want to know that the fix method is available .
You can contribute to kaa.
Description on this procedure you can find here.
In few words about it:
fork kaa repository here.
crete new branch with the content of branch you want to fix(release-0.10)
commit (commit message must begin with "KAA-1594:") and push changes into your fork.
create a pull request on kaa page (compare original kaa branch release-0.10 and your new edited branch)
allow changes from owners
you are done!
UPD: would be great if you describe the problem and your solution in issue on github it will help us to make official fix faster.

Resources