Paths must be non-empty strings and can't contain ".","#","$","[",or"]". How on earth do you solve this? [closed] - javascript

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
So I am trying to work with notifications from device to device and this error is driving me crazy, I don't know where I am doing wrong. I have tried everything and searched up to my best to solve this, any help is greatly appreciated. Thank you!
[EDIT : i had posted the question about another error here and it got solved but lead to this new error]
This is my FirebaseMessagingClass
package com.pappu5.navigation;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import com.google.firebase.messaging.RemoteMessage;
public class FirebaseMessaging extends
com.google.firebase.messaging.FirebaseMessagingService {
private String channelId = "com.pappu5.navigation";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
String notificationTtile = remoteMessage.getNotification().getTitle();
String notificationBody = remoteMessage.getNotification().getBody();
String clickAction = remoteMessage.getNotification().getClickAction();
String from_user_id = remoteMessage.getData().get("from_user_id");
NotificationCompat.Builder mBuilder = new
NotificationCompat.Builder(this,channelId)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(notificationTtile)
.setContentText(notificationBody)
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
int notificationId = (int) System.currentTimeMillis();
Intent intent = new Intent(clickAction);
intent.putExtra("user_id",from_user_id);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
// notificationId is a unique int for each notification that you must define
notificationManager.notify(notificationId, mBuilder.build());
}
This is Firebase index.js file
'use strict'
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNotification =
functions.database.ref('/Notifications/{user_id}/{notification_id}').
onWrite((change, context) => {
const user_id = context.params.user_id;
const notification_id = context.params.notification_id;
console.log('We have a notification to send to : ',
context.params.user_id);
const fromUser =
admin.database().ref('/Notifications/'+user_id+'/'+notification_id +
'/From').once('value');
return fromUser.then(fromUserResult => {
const from_user = fromUserResult.val();
console.log('You have new notification from : ',from_user);
const use_Query =
admin.database().ref(`/Chat_Profiles/{from_user}/name`).once('value');
const deviceToken =
admin.database().ref(`/Chat_Profiles/{user_id}/device_token`)
.once('value');
return Promise.all([use_Query,deviceToken]).then(result => {
const userName = result[0].val();
const token_id = result[1].val();
const payload = {
notification: {
title: "Friend Request",
body: userName+" has sent you request",
icon: "default",
click_action : "com.pappu5.navigation_TARGET_NOTIFICATION"
},
data : {
from_user_id: from_user
}
};
console.log(payload);
return admin.messaging().sendToDevice(token_id,payload).then(response => {
return console.log('This was the notification feature');
});
});
});
});

In 'Chat_Profiles/'+from_user+'/name', from_user is an object. The default toString of an object returns [object Object], which is why you get "/Chat_Profiles/[object Object]/name", which is being refused. You likely wanted to use user_id, and not from_user.

Related

How to validate GitHub webhook with Deno?

I'm trying to make a GitHub webhook server with Deno, but I cannot find any possible way to do the validation.
This is my current attempt using webhooks-methods.js:
import { Application } from "https://deno.land/x/oak/mod.ts";
import { verify } from "https://cdn.skypack.dev/#octokit/webhooks-methods?dts";
const app = new Application();
app.use(async (ctx, next) => {
try {
await next();
} catch (_err) {
ctx.response.status = 500;
}
});
const secret = "...";
app.use(async (ctx) => {
const signature = ctx.request.headers.get("X-Hub-Signature-256");
if (signature) {
const payload = await ctx.request.body({ type: "text" }).value;
const result = await verify(secret, payload, signature);
console.log(result);
}
ctx.response.status = 200;
});
The verify function is returning false every time.
Your example is very close. The GitHub webhook documentation details the signature header schema. The value is a digest algorithm prefix followed by the signature, in the format of ${ALGO}=${SIGNATURE}:
X-Hub-Signature-256: sha256=d57c68ca6f92289e6987922ff26938930f6e66a2d161ef06abdf1859230aa23c
So, you need to extract the signature from the value (omitting the prefix):
const signatureHeader = request.headers.get("X-Hub-Signature-256");
const signature = signatureHeader.slice("sha256=".length);
Update: Starting in release version 3.0.1 of octokit/webhooks-methods.js, it is no longer necessary to manually extract the signature from the header — that task is handled by the verify function. The code in the answer has been updated to reflect this change.
Here's a complete, working example that you can simply copy + paste into a project or playground on Deno Deploy:
gh-webhook-logger.ts:
import { assert } from "https://deno.land/std#0.177.0/testing/asserts.ts";
import {
Application,
NativeRequest,
Router,
} from "https://deno.land/x/oak#v11.1.0/mod.ts";
import type { ServerRequest } from "https://deno.land/x/oak#v11.1.0/types.d.ts";
import { verify } from "https://esm.sh/#octokit/webhooks-methods#3.0.2?pin=v106";
// In actual usage, use a private secret:
// const SECRET = Deno.env.get("SIGNING_SECRET");
// But for the purposes of this demo, the exposed secret is:
const SECRET = "Let me know if you found this to be helpful!";
type GitHubWebhookVerificationStatus = {
id: string;
verified: boolean;
};
// Because this uses a native Request,
// it can be used in other contexts besides Oak (e.g. `std/http/serve`):
async function verifyGitHubWebhook(
request: Request,
): Promise<GitHubWebhookVerificationStatus> {
const id = request.headers.get("X-GitHub-Delivery");
// This should be more strict in reality
assert(id, "Not a GH webhhok");
const signatureHeader = request.headers.get("X-Hub-Signature-256");
let verified = false;
if (signatureHeader) {
const payload = await request.clone().text();
verified = await verify(SECRET, payload, signatureHeader);
}
return { id, verified };
}
// Type predicate used to access native Request instance
// Ref: https://github.com/oakserver/oak/issues/501#issuecomment-1084046581
function isNativeRequest(r: ServerRequest): r is NativeRequest {
// deno-lint-ignore no-explicit-any
return (r as any).request instanceof Request;
}
const webhookLogger = new Router().post("/webhook", async (ctx) => {
assert(isNativeRequest(ctx.request.originalRequest));
const status = await verifyGitHubWebhook(ctx.request.originalRequest.request);
console.log(status);
ctx.response.status = 200;
});
const app = new Application()
.use(webhookLogger.routes())
.use(webhookLogger.allowedMethods());
// The port is not important in Deno Deploy
await app.listen({ port: 8080 });

Send message to microsoft teams channel using nodejs

I am able to acquire access token but not sure how to send messages because it requires a user and my app is a backend app(nodejs script). On graph explorer, it works.
The code snippet on graph explorer is:
const options = {
authProvider, //I need this value
};
const client = Client.init(options);
const chatMessage = {body: {content: '#.####.#'}};
await client.api('/teams/my-team-id/channels/my-channel-id/messages')
.post(chatMessage);
How do I get authProvider in nodejs?
I tried using MSALAuthenticationProviderOptions but there seems to be an issue (as mentioned in their github repo) by following these steps: https://www.npmjs.com/package/#microsoft/microsoft-graph-client.
You need to run this in the context of an application instead of a user. The Microsoft Graph JavaScript library now supports Azure TokenCredential for acquiring tokens.
const { Client } = require("#microsoft/microsoft-graph-client");
const { TokenCredentialAuthenticationProvider } = require("#microsoft/microsoft-graph-client/authProviders/azureTokenCredentials");
const { ClientSecretCredential } = require("#azure/identity");
const { clientId, clientSecret, scopes, tenantId } = require("./secrets"); // Manage your secret better than this please.
require("isomorphic-fetch");
async function runExample() {
const credential = new ClientSecretCredential(tenantId, clientId, clientSecret);
const authProvider = new TokenCredentialAuthenticationProvider(credential, { scopes: [scopes] });
const client = Client.initWithMiddleware({
debugLogging: true,
authProvider,
});
const chatMessage = {body: {content: '#.####.#'}};
const res = await client.api('/teams/my-team-id/channels/my-channel-id/messages')
.post(chatMessage);
console.log(res);
}
runExample().catch((err) => {
console.log("Encountered an error:\n\n", err);
});
This sample came from:
https://github.com/microsoftgraph/msgraph-sdk-javascript/tree/dev/samples/tokenCredentialSamples/ClientCredentialFlow

How to debug an ApolloServer's context function?

I'm trying to follow the GraphQL tutorial (https://www.apollographql.com/docs/tutorial/resolvers/), but I'm getting an error in the playground when I try to book a trip, with a stack trace starting like this:
"TypeError: Cannot read property 'id' of null",
" at UserAPI.bookTrips (/Users/kurtpeek/Documents/Scratch/fullstack-tutorial/start/server/src/datasources/user.js:35:38)",
In src/index.js, the ApolloServer (https://www.apollographql.com/docs/apollo-server/api/apollo-server/) is defined with an asynchronous context() function like so:
const { ApolloServer } = require('apollo-server');
const typeDefs = require('./schema');
const { createStore } = require('./utils');
const resolvers = require('./resolvers');
const LaunchAPI = require('./datasources/launch');
const UserAPI = require('./datasources/user');
const isEmail = require('isemail');
const store = createStore();
const server = new ApolloServer({
context: async ({ req }) => {
debugger;
const auth = (req.headers && req.headers.authorization) || '';
const email = Buffer.from(auth, 'base64').toString('ascii');
if (!isEmail.validate(email)) return { user: null };
const users = await store.users.findOrCreate({ where: { email }});
const user = users && users[0] ? users[0] : null;
return { user: { ...user.dataValues }};
},
typeDefs,
resolvers,
dataSources: () => ({
launchAPI: new LaunchAPI(),
userAPI: new UserAPI({ store })
})
});
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
Since the error I'm seeing is the result of the context's user being null, I would like to step through the context() method to inspect the headers and see whether it contains a valid (encoded) email; as you can see I've set a debugger breakpoint at the start of that function.
However, when I run node inspect src/index.js, I immediately enter the debugger for an IntrospectionQuery:
If I press the 'Resume script execution' button, I just get back immediately to the same breakpoint.
Does this have something to do with the fact that context() is an async function? How can I step through the context() method with the debugger?
In the end, I just debugged it using console.log() commands. I had accidentally put the authorization in the 'Query Variables' section rather than the 'HTTP Headers' one. Moving it to 'HTTP Headers' produces the desired result:

Javascript functions in firebase

Getting the following error:
"Cannot read property 'userName' of undefined
at Promise.all.then.result"
Also Getting Error
"The behavior for Date objects stored in Firestore is going to change
AND YOUR APP MAY BREAK.
To hide this warning and ensure your app does not break, you need to add the
following code to your app before calling any other Cloud Firestore methods:
const firestore = new Firestore();
const settings = {/* your settings... */ timestampsInSnapshots: true};
firestore.settings(settings);
With this change, timestamps stored in Cloud Firestore will be read back as
Firebase Timestamp objects instead of as system Date objects. So you will also
need to update code expecting a Date to instead expect a Timestamp. For example:
// Old:
const date = snapshot.get('created_at');
// New:
const timestamp = snapshot.get('created_at');
const date = timestamp.toDate();
Please audit all existing usages of Date when you enable the new behavior. In a
future release, the behavior will change to the new behavior, so if you do not
follow these steps, YOUR APP MAY BREAK."
However in my android project the place where i have defined the "Date" variable i have place the "#ServerTimestamp" on top.
Appreciate the help guys.
Code:
/*eslint-disable */
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNotification = functions.firestore.document('notifications/{userEmail}/userNotifications/{notificationId}').onWrite((change, context) => {
const userEmail = context.params.userEmail;
const notificationId = context.params.notificationId;
return admin.firestore().collection("notifications").doc(userEmail).collection("userNotifications").doc(notificationId).get().then(queryResult => {
const senderUserEmail = queryResult.data().senderUserEmail;
const notificationMessage = queryResult.data().notificationMessage;
const fromUser = admin.firestore().collection("users").doc(senderUserEmail).get();
const toUser = admin.firestore().collection("users").doc(userEmail).get();
return Promise.all([fromUser, toUser]).then(result => {
const fromUserName = result[0].data().userName;
const toUserName = result[1].data().userName;
const tokenId = result[1].data().tokenId;
const notificationContent = {
notification: {
title: fromUserName + " is shopping",
body: notificationMessage,
icon: "default"
}
};
return admin.messaging().sendToDevice(tokenId, notificationContent).then(result => {
console.log("Notification sent!");
//admin.firestore().collection("notifications").doc(userEmail).collection("userNotifications").doc(notificationId).delete();
});
});
});
});
Make sure the document you're request actually exists. data() will return undefined if it doesn't. You can use the exists property on the resulting DataSnapshot to check if a document was actually found.

Parsing error Javascript [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
Getting a parsing error in javascript while deploying firebase functions... Its showing unexpected token which if i'm not mistaken means that there is an unexpected character somewhere... Stuck here for weeks now... Can somone help me out please
Code
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.sendNotification = functions.database.ref(`/Notifications/${user_id}/${notification_id}/`).onWrite((change, context) => {
const user_id = context.params.user_id;
const notification_id = context.params.notification_id;
console.log('We have a notification to send to ', user_id);
if (!change.after.val()) {
return console.log("A Notification has been deleted from the database", notification_id);
}
const fromUser = admin.database().ref('/Notifications/${user_id}/${notification_id}').once('value');
return fromUser.then(fromUserResult => {
const fromUserId = fromUserResult.val().from;
console.log('You have a new notification from : ', from_user_id);
const userQuery = admin.database().ref('UserData/${fromUserId}/name').once('value');
return userQuery.then(userResult => {
const userName = userResult.val();
const deviceToken = admin.database().ref(`/UserData/${user_id}/TokenID`).once('value');
return deviceToken.then(result => {
const token_id = result.val();
const payload = {
notification: {
title: '${userName}',
body: "You have recieved a new Message",
icon: "default",
click_action: "com.appmaster.akash.messageplus_TARGET_NOTIFICATION"
},
data: {
from_user_id: fromUserId,
from_user_name: userName
}
};
return admin.messaging().sendToDevice(token_id, payload).then(response => {
return console.log('This was the notofication Feature');
});
});
});
});
You're missing two pairs of }) at the end of the file. So:
...
return admin.messaging().sendToDevice(token_id, payload).then(response =>{
return console.log('This was the notofication Feature');
});
});
});
});
});
It is understandably impossible to see this with your current code.
The lack of indentation makes it incredibly hard to parse. That's why I passed the code through http://jsbeautifier.org/, which makes it much easier to parse.
I also recommend using a tool like https://eslint.org/demo/ to make it easier to find mistakes like this.
you'll still have few bugs in your code. on three places you're using single quote ' instead of back-tick `
...
const fromUser = admin.database().ref(`/Notifications/${user_id}/${notification_id}`).once('value');
...
const userQuery = admin.database().ref(`UserData/${fromUserId}/name`).once('value');
...
const payload = {
notification: {
title: `${userName}`,
body: "You have recieved a new Message",
icon: "default",
click_action: "com.appmaster.akash.messageplus_TARGET_NOTIFICATION"
},
data: {
from_user_id: fromUserId,
from_user_name: userName
}
};

Categories