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
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 };
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!
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?
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)
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.