My request table is:
type RequestService
#model
#auth(
rules: [
{ allow: groups, groups: ["Consumers"], operations: [read, create, update] }
{ allow: groups, groups: ["Providers"], operations: [read, update] }
]
) {
id: ID!
consumerID: ID!
providerID: ID
request_detail: String
}
I have a subscription on the updateRequestService mutation:
type Subscription {
onUpdateRequestServiceByID(id: ID!): RequestService
#aws_subscribe(mutations: ["updateRequestService"])
}
I have a page that lists all the records for the RequestService, upon clicking on one record, it opens a details page for the single record.
On the details page, I've called the subscription to listen to any updates done on the RequestService.
const [request, setRequest] = React.useState(route.params.requestID)
React.useEffect(() => {
(async () => {
const abortController = new AbortController();
const subscribe = await API.graphql(graphqlOperation(onUpdateRequestServiceByID, { id: request.id })).subscribe(
{
next: (data) => {
console.log("data", data.value.data.onUpdateRequestServiceByID);
setRequest(data.value.data.onUpdateRequestServiceByID);
},
error: (err) => console.log("err", err),
}
);
return () => {
subscribe.unsubscribe();
abortController.abort();
};
})();
}, []);
Unfortunately, I don't get any console.log's back, I get no response. I've also tried this on the AppSync Queries interface, but doesn't listen to updates on a record.
Any assistance on why I'm not getting the response?
Related
One of my ideas would be to overwrite the request command, but I don't know how to handle the response object.
A snippet I already have:
Cypress.Commands.overwrite(
'request',
(
originalFn: Cypress.CommandOriginalFn<'request'>,
options: Partial<Cypress.RequestOptions>
): void | Cypress.Chainable<Cypress.Response<unknown>> => {
return originalFn(options);
}
);
My other idea would be to intercept all requests, but there are already interceptors added and you can not have two for one request.
beforeEach(() => {
cy.intercept(
{
url: '*/**',
},
req => {
// tried with 'after:response' too
req.on('response', res => {
cy.log(`${res.headers['x-custom-header']}`);
});
}
);
});
Is there any other way to log a custom header value for all request?
My final working solution was to add this code to /support/index.ts
beforeEach(() => {
cy.intercept({ url: '*', middleware: true }, req => {
req.on('after:response', (res => {
const customHeaderKey = 'x-custom-header';
const customHeaderValue = res.headers[customHeaderKey];
if (customHeaderValue) {
const message = JSON.stringify({ [customHeaderKey]: customHeaderValue });
Cypress.log({ message }).finish();
}
}));
});
});
I try to make a query to see the list of users. My custom lambda function (which I attached as policy) is as follows:
const aws = require('aws-sdk');
const ddb = new aws.DynamoDB();
exports.handler = async (event, context) => {
if (!event.request.userAttributes.sub) {
console.log("Error: No user was written to DynamoDB")
context.done(null, event);
return;
}
// Save the user to DynamoDB
const date = new Date();
const params = {
Item: {
'id': { S: event.request.userAttributes.sub },
'__typename': { S: 'User' },
'username': { S: event.userName },
'email': { S: event.request.userAttributes.email },
'createdAt': { S: date.toISOString() },
'updatedAt': { S: date.toISOString() },
},
TableName: process.env.USERTABLE,
}
try {
await ddb.putItem(params).promise();
console.log("Success");
} catch (e) {
console.log("Error", e);
}
context.done(null, event);
}
And the schema model is as follows:
type User #model
#auth(rules: [
{ allow: public, operations: [read]}
{ allow: owner }
])
{
id: ID!
username: String!
email: String!
}
Although there is one user in the dynamoDb, when I make a query by:
query listUsers {
listUsers {
items {
email
id
username
}
}
}
the result is as follows:
{
"data": {
"listUsers": {
"items": []
}
}
}
As can be seen, the array of "items" is empty, the items are not shown, when I look at the console dynamoDb table, I see user items with id, username and email values. But it should give the results, where do I make mistake? Meanwhile I am new on aws-amplify.
I want to return data coming from db to the api. The data is being logged but not showing on the graphql api.
const express = require('express');
const bodyParser = require('body-parser');
const graphqlHttp = require('express-graphql');
const { buildSchema } = require('graphql');
var mysql = require('mysql');
const app = express();
//start mysql connection
var connection = mysql.createConnection({
host : 'localhost', //mysql database host name
user : 'root', //mysql database user name
password : '', //mysql database password
database : 'test' //mysql database name
});
connection.connect(function(err) {
if (err) throw err
})
//end mysql connection
app.use(bodyParser.json());
app.use(
'/graphql',
graphqlHttp({
schema: buildSchema(`
type users {
id: String!
username: String!
password: String!
role: String!
name: String!
photo: String!
}
type RootQuery {
getUsers: [users!]!
}
type RootMutation {
createUsers(name: String): String
}
schema {
query: RootQuery
mutation: RootMutation
}
`),
rootValue: {
getUsers: () => {
connection.query('select * from users', function (error, results, fields) {
if (error) throw error;
console.log(JSON.stringify(results))
return JSON.stringify(results) ;
});
},
createUsers: (args) => {
const eventName = args.name;
return eventName;
}
},
graphiql: true
})
);
app.listen(3000);
RESULT:
query
{
getUsers {
id
}
}
OUTPUT:
{
"errors": [
{
"message": "Cannot return null for non-nullable field RootQuery.getUsers.",
"locations": [
{
"line": 3,
"column": 3
}
],
"path": [
"getUsers"
]
}
],
"data": null
}
This is your resolver:
getUsers: () => {
connection.query('select * from users', function (error, results, fields) {
if (error) throw error;
//users = results;
console.log(JSON.stringify(results));
return JSON.stringify(results) ;
});
},
A GraphQL resolver must return either a value or a Promise that will resolve to a value. However, here, you're not returning either. Keep in mind that callbacks are invoked asynchronously, so returning a value inside a callback does nothing (in most cases).
You really should use something like promise-mysql instead of mysql, but you can still wrap a callback with a Promise and return that Promise. Something like this should work:
getUsers: () => {
// Note, we have to return the Promise here
return new Promise((resolve, reject) => {
connection.query('select * from users', (error, results, fields) => {
if (error) {
reject(error)
} else {
// Don't stringify
resolve(results)
}
})
})
},
getUsers: () => {
/* 👉 return 👈 */ connection.query('select * from users', function (error, results, fields) {
if (error) throw error;
//users = results;
console.log(JSON.stringify(results));
return JSON.stringify(results) ;
});
},
Your getUsers function doesn't return anything. I believe you're missing the return statement I've highlighted in the above comment.
Incidentally, it's best practices in GraphQL to ensure all the root fields (such as getUsers) are nullable, have a read of this article to find out why.
delete (!) from field definition in schema
I am creating a simple chat app. I have three entities: rooms, messages and users.
I have a fake API that returns a response like this:
[{
id: 1,
name: 'room1',
avatar: 'some img url',
messages: [
{
id: 1,
text: 'some text',
user: {
id: 1,
username: 'Peter Peterson',
avatar: 'some img url'
}
]
}]
And my action looks like this:
getAllRooms({ commit }) {
commit(GET_ALL_ROOMS_REQUEST);
return FakeApi.getAllRooms()
.then(
rooms => {
const { entities } = normalize(rooms, room);
console.log(entities);
commit(GET_ALL_ROOMS_SUCCESS, {
rooms: entities.rooms, byId: rooms.map(room => room.id)
});
commit(GET_ALL_MESSAGES_SUCCESS, { messages: entities.messages });
commit(GET_ALL_USERS_SUCCESS, { users: entities.users });
},
err => commit(GET_ALL_ROOMS_ERROR)
)
}
And my mutations look like this:
[GET_ALL_ROOMS_REQUEST](state) {
state.loading = true;
},
[GET_ALL_ROOMS_SUCCESS](state, payload) {
state.rooms = payload.rooms;
state.byId = payload.byId;
state.loading = false;
},
[GET_ALL_ROOMS_ERROR]() {
state.error = true;
state.loading = false;
}
And my component calls the action like this:
{
mounted() {
this.getAllRooms();
}
}
These are my schema definitions:
const user = new schema.Entity('users');
const message = new schema.Entity('messages', {
user: user
});
const room = new schema.Entity('rooms', {
messages: [message]
})
when i check the response in then method after FakeApi.getAllRooms() every object is wrapped in some weird Observer, and I pass it like that to normalize and normalize returns some weird response.
What am I doing wrong?
The problem wasn't with vuejs, it was with the way I made the normalizr schemas. Because my response is an array at the root I should have had a new rooms array schema, like so:
const user = new schema.Entity('users');
const message = new schema.Entity('messages', {
user: user
});
const room = new schema.Entity('rooms', {
messages: [message]
});
const roomsSchema = [room];
And then use it like this: normalize(rooms, roomsSchema)
Im trying to set rules to Firestore allowing all user to read and write around if they're signed in.
I already have my Authentication working with Firebase, using email and password.
But the simplest auth rule I write, it just throw me an error.
Im trying to make Firestore work with this rule:
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth.uid != null;
}
}
}
But when I try to write to Firestore I got this:
If I try the Function Helpers Approach:
service cloud.firestore {
//Function
function isSignedIn() {
return request.auth.uid != null;
//Also tried with "request.auth != null"
}
//Rules
match /databases/{database}/documents {
match /{document=**} {
allow read: if isSignedIn();
allow write: if isSignedIn();
//Also tried with "allow read, write: if isSignedIn();"
}
}
}
It also throw me the same error.
I also tried matching custom paths, like match /Restaurants/{RestaurantsId} ... but also didn’t work…
But if I remove everything and I use the following default rule:
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write;
}
}
}
it does work…
I’ve followed Firestore Documentation, AngularFirebase Video Tutorial, looked at github and here to similar cases and I still cant make it work. I see everybody that has tried this got this working perfectly, but it does not with me :S.
––––UPDATE 1––––
Here is how Im calling the set method of Firestore:
When I press a “Save Button” I call this helper function:
saveMealHandler() {
const { mealImage, mealCategory, mealName, mealIngredients, mealPrice, mealOptions, mealExtras, user } = this.props;
const id = this.props.completeMenu.length;
const { navigation } = this.props;
this.props.saveMeal({
key: id,
name: mealName,
avatar: mealImage,
ingredients: mealIngredients,
price: mealPrice,
category: mealCategory,
options: mealOptions,
extras: mealExtras
}, user);
this.props.cleanAllInputs();
}
and this helper call’s the following action creator which writes on Firestore:
export const saveMeal = (newMeal, user) => {
const db = firebase.firestore();
const docRef = db.collection('Resto').doc(user);
return dispatch => {
docRef.set({
isWorking: 'JALAPEÑO!'
})
.then(() => {
console.log('Document successfully written!');
})
.catch((error) => {
console.error('Error writing document: ', error);
});
dispatch({ type: SAVE_NEW_MEAL_TO_MENU, payload: newMeal });
};
};
––––UPDATE 1––––
––––UPDATE 2––––
This is the function which capture the user and password and calls the action creator:
onButtonPress() {
const { email, password } = this.props;
console.log(email, password);
this.props.loginUser({ email, password });
}
This is the action creator im using for register and login in an user
export const loginUser = ({ email, password }) => {
return (dispatch) => {
dispatch({ type: LOGIN_USER_START });
firebase.auth().signInWithEmailAndPassword(email, password)
.then(user => userLoginSuccess(dispatch, user))
.catch(() => {
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(user => userLoginSuccess(dispatch, user))
.catch(() => userLoginFail(dispatch));
});
};
};
//Helpers
const userLoginSuccess = (dispatch, user) => {
dispatch({ type: LOGIN_USER_SUCCESS, payload: user.uid });
};
const userLoginFail = (dispatch) => {
dispatch({ type: LOGIN_USER_FAIL });
};
And this is how I know this functions are working:
––––UPDATE 2––––
With all my attempts I think may be I missed to install something without knowing in or there is something wrong when I add the condition. But It this moment I just prefer to ask.
I also recorded a video so you can see the issue, here it is:
https://youtu.be/9fmWk7-HjZ4
Thanks to everyone.
i came across same problem
import all firebase cdn below
https://www.gstatic.com/firebasejs/6.4.0/firebase-app.js
https://www.gstatic.com/firebasejs/6.4.0/firebase-auth.js
https://www.gstatic.com/firebasejs/6.4.0/firebase-firestore.js