Can't get subcollection in Firestore - Kotlin - firebase

I'm doing a little test app and I'm trying to get all products from a market.
The current database schema is:
markets:[
market1: {},
market2: {},
market3: {
name: "",
products: [
item1: {},
item2: {}
]
}
]
my code in kotlin is:
try {
db.collection("markets").document(marketId).collection("products")
.get()
.addOnCompleteListener { task ->
if (task.isSuccessful) {
var products = mutableListOf<Product>()
for (document in task.result) {
products.add(
Product(
document.id,
document.get("name").toString(),
true
)
)
}
//updateList(products)
} else {
Log.e("Getting markets", "Error getting documents.", task.exception)
}
}
}catch (e : Exception){ }
I also tried replacing the db.collection().document().collection() with:
db.collection("markets/$marketId/products")
however it stills returns 0 items, ( there are two).
Any help would be appreciated

After I tested a lot of variations I noticed that no matter what collection I entered it didn't give me any results, even with collections that worked on other activities.
so I went to application manager on the phone an clear cache and delete data, then I opened again and now is working.

Related

How to check if an entry already exists when posting in Dynamo DB with AWS Amplify

In an Amplify w/ graphql project, I have a conversation schema which both members of the conversation saved in an array. When creating a conversation, I only want one conversation to exists between two users. So I want the creating of the conversation entry to fail when a conversation already exists.
When creating the mutation, I tried to use the condition input to let the query fail when the condition is false. But I have not found a solution to check the members array.
Any advice on using the conditions input is appreciated!
type Conversation
#model {
id: ID!
members: [String!]!
...
}
const createConversationInput: CreateConversationInput = {
members: [userOneId, userTwoId],
...
};
const createConversationMutation = (await API.graphql({
query: createConversation,
variables: {
input: createConversationInput,
condition: {
and: [
{ not: { members: { contains: userOneId } } },
{ not: { members: { contains: userTwoId } } },
],
},
},
...
})) as { data: CreateConversationMutation };

Firestore Call is freezing my app temporarily - Xcode/iOS/Firestore

I am making a call in my SwiftUI app which will add a document to my Cloud Firestore database. The issue is this is taking around 5 seconds to complete and rendering the app useless for those 5 seconds. I think this could also be down to the cloud functions running when the document is added however I am not sure.
I have tried, rather unsuccessfully so far I might add, to look at using other threads however this is to no avail. Can anyone provide some advice?
This is how I am calling the function:
Button(action: {
DispatchQueue.main.async{
addCard(time: "", text: "\(userSettings.username) Recorded")
}
}){
Text("Another One")
}
This is the actual function that is running.
func addCard(_ card: Card) {
do {
_ = try store.collection(path).addDocument(from: card)
} catch {
fatalError("Unable to add card: \(error.localizedDescription).")
}
}
As I think it could also be my Cloud Functions causing an issue, here it is too:
exports.logActivities = functions.firestore.document('/{collection}/{id}')
.onCreate((snap, context) => {
return admin.messaging().send({
"notification": {
"title": 'New Record',
"body": snap.data()['text'] + ' a new "Tell Em Lad"'
},
"apns": {
"payload": {
"aps": {
"sound": 'notiSound.wav'
}
}
},
"topic": 'client'
});
})
Any help would be greatly appreciated!

AppSync client query not returning complete data response

I am having an issue getting results back from my AppSync API via AWSAppSyncClient. I can run the query in the AWS AppSync console and get the complete results, however when I run the query from my client the portion of the results I am looking for returns an empty array.
I have tried slimming down the query to return less results, as I read at one point that dynamo will run a filter on the results being returned if you do not provide your own. I have also read this could have something to do with the partition keys used in the dynamoDB table, however AppSync provisioned that resource for me and handled the initial config. I am new to working with AppSync so I am sort of drawing a blank on where to even start looking for the issue because there is not even an error message.
The Query I am running
export const getUserConversations = `query getUser($id: ID!) {
getUser(id: $id) {
id
conversations {
items {
conversation{
id
associated{
items{
convoLinkUserId
}
}
}
}
}
}
}
`;
Call being made in a redux actions file
export const getUserConvos = (id) => async dispatch => {
AppSyncClient.query({
query: gql(getUserConversations),
variables: {
id: id
}
}).then(res => {
console.log("RES FROM CONVO QUERY", res)
})
}
This is the response I am getting in the browser
Notice conversations.items returns an empty array.
getUser:
conversations:
items: []
__typename: "ModelConvoLinkConnection"
__proto__: Object
id: "HIDDEN_ID"
__typename: "User"
__proto__: Object
__proto__: Object
However if i run the exact same query in the playground on the AppSync console I get this...
{
"data": {
"getUser": {
"id": "HIDDEN_ID",
"conversations": {
"items": [
{
"conversation": {
"id": "HIDDEN_ID",
"associated": {
"items": [
{
"convoLinkUserId": "HIDDEN_ID"
},
{
"convoLinkUserId": "HIDDEN_ID"
}
]
}
}
},
{
"conversation": {
"id": "HIDDEN_ID",
"associated": {
"items": [
{
"convoLinkUserId": "HIDDEN_ID"
},
{
"convoLinkUserId": "HIDDEN_ID"
}
]
}
}
}
]
}
}
}
}
*HIDDEN_ID is a placeholder
I know that the objects are in my DB, however if i run the query via my react application I get nothing, and if I run it in the console on AWS I get another. I need to be able to have access to these conversations via the client. What could be causing this?

Firebase 'OR' condition on single field

In my application the main entity is threads, I mean sneakers, jackets, t-shorts and so on.
This is firebase db:
I have logic witch fetch threads by 'threadTypes'. In my app there're 3 types - outwear, footwear and accessory.
That is code:
extension GoodsViewController {
func fetchThreads(completion: #escaping (Swift.Void) -> Swift.Void) {
self.ref
.child("threads")
.observeSingleEvent(of: .value, with: { (snapshot) in
for rest in snapshot.children.allObjects as! [FIRDataSnapshot] {
guard let restDict = rest.value as? [String: Any] else { continue }
let thread = Thread()
thread.setValuesForKeys(restDict)
if Search.searchFilters.stuffTypes.isEmpty {
self.threads.append(thread)
}
else {
if let threadType = thread.threadType {
if Search.searchFilters.stuffTypes.contains(threadType) {
self.threads.append(thread)
}
}
}
}
completion()
})
}
}
self.threads - is variable which is used as table view datasource.
Search.searchFilters.stuffTypes - array which contains types for search.
As you see I fetch all threads and then check if current thread type contains in Search.searchFilters.stuffTypes array.
My question is - is it possible to perform this checking before I fetch all threads?
In C# it should be something like that -
threads.Where(t => Search.searchFilters.stuffTypes.Contains(t.threadType)

Adding upvotes to reactjs and Firebase chatroom

https://github.com/kristinyim/ClassroomChat
I want to add an upvoting feature to the messages on this chatroom similar to what you have on GroupMe, but I'm new to React and built this off of a tutorial so don't know where to even begin. I'm good with webdev but am just getting started with the basics of React.js and Firebase. Thanks!
NB: There are many ways to achieve this, so the following is just a suggestion.
First you must think of how you want to store your data in the database. If you have users, messages and message-likes, you could structure it like this:
"root": {
"users": {
"$userId": {
...
"messages": {
"$messageId1": true,
"$messageId2": true,
...
}
}
},
"messages": {
"$messageId": {
"author": $userId,
"timestamp": ServerValue.TIMESTAMP
}
},
"likesToMessages": {
"$messageId": {
"$likeId": {
liker: $userId,
"message": $messageId,
"timestamp": ServerValue.TIMESTAMP
}
}
}
}
Whenever a user clicks "like" on a message, you want to write to
var messageId = ?; // The id of the message that was liked
var like = {
liker: currentUserId, // id of logged in user
message: messageId,
timestamp: firebase.database.ServerValue.TIMESTAMP
};
firebase.database.ref().child('likesToMessages').child(messageId).push(like);
Then you get a new like in the database, matching the proposed structure.
Then, when you want to read and show the count of likes for a message, you can do like this:
const Message = React.createClass({
propTypes: {
message: React.PropTypes.object,
messageId: React.PropTypes.string // you need to add this prop
}
componentWillMount() {
firebase.database.ref().child('likesToMessages').child(this.props.messageId).on('value', this.onLikesUpdated)
}
onLikesUpdated(dataSnapshot) {
var likes = snap.val();
this.setState({
likes
});
}
render() {
const {name, message} = this.props.message;
const emojifiedString = emoji.emojify(message);
return (
<p>
{name}: {emojifiedString} [{this.state.likes.length}♥]
</p>
);
}
});
Also, in your database security rules, you'd want to index by timestamp for message and like so you can quickly query the newest messages.
Also, feel free to check out a similar app I made, code in GitHub and demo on wooperate.firebaseapp.com.

Resources