So I am using cryptojs and firebase to send an encrypted message and then display that encrypted message in the chat box. I am able to send a regular message without any encryption just fine but when I encrypt the message. I end up getting this error:
Uncaught Error: Reference.push failed: first argument contains a function in property 'messages.text.init' with contents = function () {
subtype.$super.init.apply(this, arguments);
I think because I am pushing an encryption of the message it is a function.
Not sure though.
messageForm.addEventListener("submit", function (e) {
e.preventDefault();
var user = auth.currentUser;
var userId = user.uid;
if (user.emailVerified) {
// Get the ref for your messages list
var messages = database.ref('messages');
// Get the message the user entered
var message = messageInput.value;
var myPassword = "11111";
var myString = CryptoJS.AES.encrypt(message, myPassword);
// Decrypt the after, user enters the key
var decrypt = document.getElementById('decrypt')
// Event listener takes input
// Allows user to plug in the key
// function will decrypt the message
decrypt.addEventListener('click', function (e) {
e.preventDefault();
// Allows user to input there encryption password
var pass = document.getElementById('password').value;
if (pass === myPassword) {
var decrypted = CryptoJS.AES.decrypt(myString, myPassword);
document.getElementById("demo0").innerHTML = myString;
// document.getElementById("demo1").innerHTML = encrypted;
document.getElementById("demo2").innerHTML = decrypted;
document.getElementById("demo3").innerHTML = decrypted.toString(CryptoJS.enc.Utf8);
}
});
// Create a new message and add it to the list.
messages.push({
displayName: user.displayName,
userId: userId,
pic: userPic,
text: myString,
timestamp: new Date().getTime() // unix timestamp in milliseconds
})
.then(function () {
messageStuff.value = "";
})
.catch(function (error) {
windows.alert("Your message was not sent!");
messageStuff;
});
Look at this line of code:
var myString = CryptoJS.AES.encrypt(message, myPassword);
myString isn't a string. I believe it's a CipherParams object. (Reading from the documentation here.) You're then trying to make that object a field in the database:
messages.push({
displayName: user.displayName,
userId: userId,
pic: userPic,
text: myString,
timestamp: new Date().getTime() // unix timestamp in milliseconds
})
This isn't going to work. You need to store a string instead of an object there. Try calling toString() the return value of encrypt() to store a string that you can later convert back to whatever you need:
messages.push({
displayName: user.displayName,
userId: userId,
pic: userPic,
text: myString.toString(),
timestamp: new Date().getTime() // unix timestamp in milliseconds
})
Related
I am trying to send the data of my user to firebase using the code given below:
var firestore = firebase.firestore();
var messagesRef = firestore.collection("BookingData");
//listen for submit
document.getElementById('bookingForm').addEventListener('submit',submitForm);
function submitForm(e){
e.preventDefault();
//get values
var email = getInputVal('email');
var packageFields = getInputVal('packageFields');
var name = getInputVal('name');
var phone = getInputVal('phone');
var date = getInputVal('date');
}
// function to get form values
function getInputVal(id) {
return document.getElementById(id).value;
}
//save messages
function saveMessage(email, packageFields, name, phone, date) {
messageRef.add({
email:email,
packageFields:packageFields,
name:name,
phone:phone,
date:date
}).then(function(docRef) {
console.log("Document written with ID: ", docRef.id);
})
.catch(function(error) {
console.error("Error adding document: ", error);
});
}
But nothing is happening.
I am not able to send the data to firebase databse.
it also shows a warning called:
[2020-05-30T03:38:27.083Z] #firebase/app:
Warning: Firebase is already defined in the global scope. Please make sure
Firebase library is only loaded once.
How can I Solve this problem? Please Help/\
Thanks in advance.
Ok, I got The Error I was Not calling The Function. The correct code is:
var firestore = firebase.firestore();
var messagesRef = firestore.collection("BookingData");
//listen for submit
document.getElementById('bookingForm').addEventListener('submit',submitForm);
function submitForm(e){
e.preventDefault();
//get values
var email = getInputVal('email');
var packageFields = getInputVal('packageFields');
var name = getInputVal('name');
var phone = getInputVal('phone');
var date = getInputVal('date');
saveMessage(email, packageFields, name, phone, date);
}
// function to get form values
function getInputVal(id) {
return document.getElementById(id).value;
}
//save messages
function saveMessage(email, packageFields, name, phone, date) {
messageRef.add({
email:email,
packageFields:packageFields,
name:name,
phone:phone,
date:date
}).then(function(docRef) {
console.log("Document written with ID: ", docRef.id);
})
.catch(function(error) {
console.error("Error adding document: ", error);
});
}
I'm trying to put the values at addUser function to push to another function object. I dont how and what to put at the prompt value to .id and .pwd.
var memArray =[];
function addUserObject(id, password){
this.id = id;
this.pwd = password
}
var addUserObj = new addUserObject ("")
// i dont how and what to put the prompt value to .id and .pwd
memArray.push(addUserObj);
console.log(memArray)
function addUser(){
var addUsername = prompt ("Type your username");
var addPwd = prompt ("Type your password");
addUserObject(addUsername,addPwd)
At the risk of not having understood your problem, you can't add the user until you know the username and password (until the prompt requests are finished).
Is this what you are trying to do?:
// Initialize an empty array
var memArray =[];
// Define helper function to add a user to the array
function addUserObject(id, password){
// Define a user object
var userObj = {
id: id,
password: password
};
// Push the new user into the array
memArray.push(userObj);
}
// Define a function that requests user and pwd
function addUser(){
// Request username and pwd
var addUsername = prompt ("Type your username");
var addPwd = prompt ("Type your password");
// Call to add the user to the array
addUserObject(addUsername, addPwd);
}
// Call the 'addUser' function to request a new user
addUser();
// Print the array to console (it should contain one user)
console.log(memArray);
I have commented the code excessively just so you understand.
One way is to add the functionality to this, same as the properties you create:
function addUserObject(id, password){
this.id = id;
this.pwd = password;
this.addUsername = function(){this.id = prompt("Type your username")}.bind(this);
this.addPwd = function(){this.pwd = prompt("Type your password")}.bind(this);
};
var addUserObj = new addUserObject();
//REM: Adding username
addUserObj.addUsername();
console.log(addUserObj);
//REM: Adding paddword
addUserObj.addPwd();
console.log(addUserObj);
The second way is to ask for it on creation:
function addUserObject(id, password){
this.id = id;
this.pwd = password;
}
var addUserObj = new addUserObject(prompt("name?"), prompt("pw?"));
console.log(addUserObj);
Once you create an object, it has to contain properties along with methods, so it's ok to implement all inside an instance.
var memArray =[];
function addUserObject(){
var id, pwd;
this.getData = function(){
return {
id: this.id,
pwd: this.pwd
}
}
this.setData = function(){
this.id = prompt ("Type your username");
this.pwd = prompt ("Type your password");
}
return this.setData();
}
var user = new addUserObject;
memArray.push(user.getData());
console.log(memArray)
If you want to use constructors functions, then you can create a function which return a new object:
function userObject(id, name, password){
this.id = id;
this.name = name;
this.pwd = password
}
let userBob = new userObject(1, 'Bob', 'fooPsw');
let userJoseph = new userObject(2, 'Joseph', 'barPsw');
let userJohn = new userObject(3, 'John', 'barPsw');
and then just push these objects into array:
let users = [];
function addUser(id, name, password)
{
let user = new userObject(id, name, password);
users.push(user);
}
addUser(1, 'Bob', 'fooPsw');
addUser(2, 'Joseph', 'barPsw');
addUser(3, 'John', 'barPsw');
The whole code looks like this:
function userObject(id, name, password){
this.id = id;
this.name = name;
this.pwd = password
}
let users = [];
function addUser(id, name, password)
{
let user = new userObject(id, name, password);
users.push(user);
}
addUser(1, 'Bob', 'fooPsw');
addUser(2, 'Joseph', 'barPsw');
addUser(3, 'John', 'barPsw');
console.log(users);
I want to signup new users (through auth) and then add them (with their names and other info) to my user list database in realtime DB. I can't figure out what I'm doing wrong. Authentication works great but the new user is not being added to the DB.
var fname = document.getElementById('fname').value;
var lname = document.getElementById('lname').value;
var email = document.getElementById('email').value;
in the code below, I register them then add their names to the DB and then send a verification email.
function handleRegister() {
var ref = firebase.database().ref();
console.log(email);
console.log(fname);
if (email.length < 4) {
alert('Please enter an email address.');
return;
}
if (password.length < 4) {
alert('Please enter a password.');
return;
}
firebase.auth().createUserWithEmailAndPassword(email, password).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
var uid = firebase.auth().currentUser.uid;
// [START_EXCLUDE]
if (errorCode == 'auth/weak-password') {
alert('The password is too weak.');
firebase.auth().onAuthStateChanged(user => {
if(user) {
var postData = {
Fullname: fname + lname,
email: email,
};
// Write the new post's data simultaneously in the posts list and the user's post list.
var updates = {};
updates['/Users/' + uid ] = postData;
return firebase.database().ref().update(updates);
}
})
} else {
console.log(error);
}
})
Authentication and send email verification works fine but names are not being added to the DB. Also if there is a better approach to achieve auth,add to DB and send email verification, please let me know. Please help.
This is the updated addition
var addusertoDB = function(user){
var uid = firebase.getAuth().uid;
var postData = {
Firstname: fname,
Lastname: lname,
email: email,
}
// Get a key for a new Post.
var newPostKey = firebase.database().ref().child('Users').push().uid
// Write the new post's data simultaneously in the posts list and the user's post list.
var updates = {};
updates['/Users/' + newPostKey] = postData;
// updates['/user-posts/' + '/' + newPostKey] = postData;
return firebase.database().ref().update(updates);
}
and handle register has been updated to
firebase.auth().createUserWithEmailAndPassword(email, password).then(
addusertoDB).catch(handleCreateUserError);
it's finally being added to the DB (without the uid) but firebase.getAuth().uid is not getting the uid. the error I'm getting is "firebase.getAuth is not a function"
You are trying to handle both the errors and the user update in the same function you have passed to catch(). This means that any code inside that function is only run when firebase.auth().createUserWithEmailAndPassword(email, password) fails.
From the firebase documentation:
createUserWithEmailAndPassword
createUserWithEmailAndPassword(email, password) returns
firebase.Promise containing non-null firebase.User
Creates a new user account associated with the specified email address
and password.
On successful creation of the user account, this user will also be
signed in to your application.
This means that on the successful creation of a user you will have access to the new user via a callback passed into then().
You probably want something like this:
var doSomethingWithNewUser = function(user) {
// Manipulate the newly created User however you like here.
// You don't have to sign them in again.
};
var handleCreateUserError = function(error) {
var errorCode = error.code;
var errorMessage = error.message;
// Do whatever you want with the error codes.
};
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(doSomethingWithNewUser)
.catch(handleCreateUserError);
As documentation says - "The JavaScript SDK does not currently support modifying Installation objects.", but what about creating these objects? is it possible to create Installation objects from cloud code?
For ex:
Parse.Cloud.define("registerForNotifications", function(request,response) {
var token = request.params.deviceToken;
var deviceType = request.params.deviceType;
var user = request.user;
var installation = new Parse.Object("Installation");
if (installation) {
installation.set("deviceToken",token);
... so on..
installation.save();
}
});
Will this work? Thank you.
Some example:
//The following Cloud Function expects two parameters: the channel to be added to this user's installations, and the object id for the user.
//It assumes that each installation has a `Pointer <_User>` back to the original user.
//...
Parse.Cloud.define("subscribeToChannel", function(request, response) {
var channelName = request.params.channel;
var userId = request.params.userId;
if (!channelName) {
response.error("Missing parameter: channel")
return;
}
if (!userId) {
response.error("Missing parameter: userId")
return;
}
// Create a Pointer to this user based on their object id
var user = new Parse.User();
user.id = userId;
// Need the Master Key to update Installations
Parse.Cloud.useMasterKey();
// A user might have more than one Installation
var query = new Parse.Query(Parse.Installation);
query.equalTo("user", user); // Match Installations with a pointer to this User
query.find({
success: function(installations) {
for (var i = 0; i < installations.length; ++i) {
// Add the channel to all the installations for this user
installations[i].addUnique("channels", channel);
}
// Save all the installations
Parse.Object.saveAll(installations, {
success: function(installations) {
// All the installations were saved.
response.success("All the installations were updated with this channel.");
},
error: function(error) {
// An error occurred while saving one of the objects.
console.error(error);
response.error("An error occurred while updating this user's installations.")
},
});
},
error: function(error) {
console.error(error);
response.error("An error occurred while looking up this user's installations.")
}
});
});
I'm creating a push notification similar to this sample code provided by Parse:
Parse.Cloud.afterSave('Activity', function(request) {
if (request.object.get("type") === ("comment") {
var message = request.user.get('displayName') + ': ';
message += request.object.get('content').trim();
var query = new Parse.Query(Parse.Installation);
query.equalTo('user', request.object.get("toUser"));
Parse.Push.send({
where:query,
data: {
alert: message,
badge: 'Increment'
}
});
}
});
My question is: in the data area of the Parse.Push.send, can I send an entire message object, where Message is a custom class I created? If so, what would that look like?
If you already have the class created and saved an object why not just send the object ID and query it asynchronously once the user goes to retrieve the push notification?
The message object does not need to waste up space and be sent via push just a pointer is required.
I'm in the process of implementing something similar and this is the route I plan to use.
You can serialize the object in JSON/XML format and then deserialize it when you receive the push notification.
You can't send objects directly. You'll get an exception (I had this issue a few days ago but didn't write the name of the exception down). The best answer is so far is by BrentonGray88.
I'm assuming you're not using Android because you included the badge: "Increment" value, but this is how I would do it:
Android code to send the notification:
Make sure the Comment object has a pointer (_User) column to the User who sent the comment. When you create the comment, include user.put("commentAuthor", ParseUser.getCurrentUser()); in your Android code so that you can always access the user who created the comment.
Now you need to query the Comment to send its objectId through to the push notification.
ParseQuery<ParseObject> query = new ParseQuery<>("Comment");
query.whereEqualTo("objectId", I AM NOT SURE WHAT CONDITION YOU WANT HERE);
query.findInBackground((comment, e) -> {
if (e == null) for (ParseObject commentObject: comment) {
String recipientObjectId = commentObject.getParseObject("commentAuthor").getObjectId();
final Map<String, Object> params = new HashMap<>();
// This is to send the notification to the author of the Comment
params.put("recipientObjectId", recipientObjectId);
// This is so we can use values from the Comment in the notification
params.put("commentObjectId", commentObject.getObjectId());
// This is a required lined
params.put("useMasterKey", true);
ParseCloud.callFunctionInBackground("pushMessage", params, new FunctionCallback<String>() {
public void done(String result, ParseException e) {
if (e == null) {
Log.d(getClass().toString(), "ANNOUNCEMENT SUCCESS");
} else {
System.out.println(e);
Log.d(getClass().toString(), "ANNOUNCEMENT FAILURE");
}
}
});
}
});
Now for the query in your Cloude Code:
Parse.Cloud.define("pushMessage", function (request, response) {
// Again, we are sending the notification to the author of the Comment
var pushQuery = new Parse.Query(Parse.Installation);
pushQuery.equalTo('user', request.params.get("recipientObjectId"));
// We retrieve information from the Comment created by that author
var commentQuery = new Parse.Query(Parse.Comment);
commentQuery.equalTo('objectId', request.params.commentObjectId);
commentQuery.get("commentObjectId", {
success: function(userObject) {
var displayName = userObject.get("displayName");
var content = userObject.get("content");
var message = displayName + ': ';
message += content.trim();
Parse.Push.send({
where: pushQuery,
data: {
alert: message
},
}, {
useMasterKey: true,
success: function () {
response.success("Success!");
},
error: function (error) {
response.error("Error! " + error.message);
}
});
console.log();
},
error: function(error) {
console.log("An error occured :(");
}
});
});
Sorry I'm not the best at JavaScript but that's kind of how I'd do it. Best of luck! :)