I am creating a frontend app based on Truffle + Webpack, following this tuto : http://truffleframework.com/tutorials/building-testing-frontend-app-truffle-3, and have no uderstanding of JavaScript at all.
The code works on truffle console and the app globally works, except for the function "append_buy_brent", adding a new element to a struct array called buy_orderbook_brent
Solidity :
contract Petroleum{
// Initialisations
address _creator;
uint user_number;
struct Baril_order {
uint price;
uint quantity;
address addr;
}
Baril_order[] buy_orderbook_brent;
mapping(address => uint) account_map;
mapping(uint => uint) user_balance;
mapping(uint => uint) number_of_brent;
function Petroleum() payable{
_creator=msg.sender;
user_number=0;
test=0;
account_map[_creator]=0;
account_map[0x7f8105da4dd1af61da7bf587766103ba8534fcdc]=1;
user_balance[account_map[msg.sender]]=100000;
number_of_brent[account_map[msg.sender]]=5;
number_of_wti[account_map[msg.sender]]=2;
debt[account_map[msg.sender]]=20;
user_balance[account_map[0x7f8105da4dd1af61da7bf587766103ba8534fcdc]]=200000;
number_of_brent[account_map[0x7f8105da4dd1af61da7bf587766103ba8534fcdc]]=7;
number_of_wti[account_map[0x7f8105da4dd1af61da7bf587766103ba8534fcdc]]=10;
debt[account_map[0x7f8105da4dd1af61da7bf587766103ba8534fcdc]]=3;
}
function append_buy_brent(uint price, uint quantity, address addr) payable {
buy_orderbook_brent.push(
Baril_order({
price:price,
quantity: quantity,
addr: addr,
})
);
}
}
JavaScript :
import { default as Web3} from 'web3';
import { default as contract } from 'truffle-contract'
import Petroleum_artifacts from '../../build/contracts/Petroleum.json'
var Petroleum = contract(Petroleum_artifacts);
var accounts;
var account;
var account1;
window.App = {
start: function() {
var self = this;
Petroleum.setProvider(web3.currentProvider);
web3.eth.getAccounts(function(err, accs) {
if (err != null) {
alert("There was an error fetching your accounts.");
return;
}
if (accs.length == 0) {
alert("Couldn't get any accounts! Make sure your Ethereum client is configured correctly.");
return;
}
accounts = accs;
account = accounts[0];
account1 = accounts[1];
self.refreshBalance1();
self.refreshBalance2();
});
},
append_buy_brent: function(){
var self = this;
var price_buy_brent= parseInt(document.getElementById("price_buy_brent").value);
var quantity_buy_brent=parseInt(document.getElementById("quantity_buy_brent").value);
this.setStatus("Initiating transaction... (please wait)");
var petro;
Petroleum.deployed().then(function(instance) {
petro = instance;
return petro.append_buy_brent(price_buy_brent,quantity_buy_brent, account, {from: account, value: web3.toWei(1000, "ether")});
}).then(function(value) {
self.setStatus("Transaction complete!");
self.refreshBalance1();
self.refreshBalance2();
}).catch(function(e) {
console.log(e);
self.setStatus("Error placing buy_brent; see log.");
});
},
}
Log :
Error: VM Exception while processing transaction: invalid JUMP at
d8abbe98e23bfa2cd66729f537c8dd23bb72c25425af350243627a30533c3b73/a8c9aca1a9b5fd638a6aa025545e1274787f3456:790
I hope I gave enough information, first time here. Thanks a lot.
it looks like a EVM bug. Could you try without putting both the contract deployment and the function call in 2 different transactions ?
https://github.com/ethereumjs/testrpc/issues/196
Related
I am working on a smart contract interaction, I started writing the contract called BuyCoffee:
contract BuyCoffee {
struct Author {
address wallet_address;
uint256 balance;
}
struct Coffee {
address author_wallet_address;
address sender_wallet_address;
uint256 value;
}
Coffee[] public coffee;
mapping (address => Author) public authors;
uint256 public total_contract_balance;
function getContractBalance() public view returns (uint256) {
return total_contract_balance;
}
...
function buymeacoffee(address author_wallet_address, address sender_wallet_address, uint256 value) public {
coffee.push(Coffee({
author_wallet_address: author_wallet_address,
sender_wallet_address: sender_wallet_address,
value: value
}));
authors[author_wallet_address].balance += value;
total_contract_balance += value;
}
}
For the frontend app, I am using the library Ether and building a metamask_controller.js
import { Controller } from "#hotwired/stimulus";
import { ethers } from "ethers";
import abi from "../contract.json" assert { type: "json" };
export default class extends Controller {
...
async buyCoffee() {
try {
const authorWalletAddress = "0x5FF0...f16F3D2";
const senderWalletAddress = userAddress;
const price = this.priceTarget.innerText;
console.log("price: ", price);
console.log("authorWalletAddress: ", authorWalletAddress);
console.log("senderWalletAddress: ", senderWalletAddress);
// execute transaction
const transaction = await contract.buymeacoffee(
authorWalletAddress,
senderWalletAddress,
{ value: ethers.utils.parseEther(price)}
);
// console.log("Processing...", transaction.hash);
await transaction.wait();
// reload the whole page
window.location.reload();
}
catch (error) {
console.log(error);
alert("Transaction failed!");
}
}
But look like that I am having an issue when calling the buyCoffee function, the console log show me the correct values:
price: 0.001
authorWalletAddress: 0x5FF....F3D2
senderWalletAddress: 0x7da....1721
Then I get the error invalid BigNumber value (argument="value", value={"value":{"type":"BigNumber","hex":"0x038d7ea4c68000"}}, code=INVALID_ARGUMENT, version=bignumber/5.7.0)
How could I solve that? Look like is something about the price that has to change from 0.001 to big number
We always pass values as string:
// you could use BN too
{ value: ethers.utils.parseEther(price.toString())}
I have a smart contract that I'm testing the first functions of, and so far everything seems fine apart from one argument of an event not being properly passed.
The contract :
// SPDX-License-Identifier: MIT
// contract that mints 10 NFTs that will then be sold on the market place
pragma solidity ^0.8.7;
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "#openzeppelin/contracts/access/Ownable.sol";
import "#openzeppelin/contracts/utils/Counters.sol";
contract MintNFT is ERC721, ERC721URIStorage, Ownable {
//Helpers
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
string[] public _allTokenURIs;
mapping(uint256 => string) public _IDtoURI;
event NFTMinted(uint256 indexed tokenId, string uri);
constructor() ERC721("Plot On Mars", "POM") {}
function bulkMint(string[] memory uris)
public
onlyOwner
{
_allTokenURIs = uris;
address to = msg.sender;
for (uint i = 0; i < uris.length; i++) {
safeMint(to, uris[i]);
}
}
function safeMint(address to, string memory uri)
internal
onlyOwner
{
_tokenIds.increment();
uint256 tokenId = _tokenIds.current();
_safeMint(to, tokenId);
_setTokenURI(tokenId, uri);
_IDtoURI[tokenId]=uri;
emit NFTMinted(tokenId, uri);
}
function getTokenId() public view returns(uint256){
return _tokenIds.current();
}
// function to view a specific URI related to a tokenID
function viewURIs(uint256 i) public view returns(string memory){
string memory unique = _allTokenURIs[i];
return unique;
}
// The following functions are overrides required by Solidity.
function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
super._burn(tokenId);
}
function tokenURI(uint256 tokenId)
public
view
override(ERC721, ERC721URIStorage)
returns (string memory)
{
return super.tokenURI(tokenId);
}
}
The test script :
const { assert, expect, expectEvent } = require("chai")
const { network, deployment, ethers, deployments } = require("hardhat")
const { developmentChains } = require("../helper-hardhat-config")
//Arrange-Act-Assert (AAA)
// if we have defined an error in our solidity code, we must wrap the logic corresponding
//in a catch/try{}
//skip test if on localhost/hardhat
!developmentChains.includes(network.name)
? describe.skip
: describe("Basic NFT minting tests", function () {
let mintNFT, deployer
let _name = "Plot On Mars"
let _symbol = "POM"
let tokensUris = [
"ipfs://QmaGmVJianGd3wzdfRNFZXWA9UeMdLFMBX5cZZSZjNeckP",
"ipfs://QmaGV6P2knFkPdStvPsNXjJjehEysfnK7e4tShJAvpuPrx",
"ipfs://QmcdbzSUFhRF98ppNHf83yhPJ2jHjP5Lpuov9Wzi4aYZF4",
"ipfs://QmP8W1KEC2td2VPn3tbEYjFBZ2yV6jZh5Fbe2rGjzqCMwS",
"ipfs://QmdL2QjcLPjd1RLwHK1GNuNQSt5b4ZXupuaGYtUi3Lqqz5",
"ipfs://QmaJqsMKbFLLTZszY2rprPRncDReLTnhHVdz2U7aScxFNS",
"ipfs://QmYeioLfMcTUNSABndwqJz7sjaeA7quF1fMGq2tziSE2T3",
"ipfs://QmW7nRHE7J5L36n9NvxspwNfSbEPRcFvDF4kUkscZHehyZ",
"ipfs://QmUcCwpskbvQydNa3rcSpCftsPAmBgovn6WnZYTeZw4NpU",
"ipfs://QmdyTVfRymf2kFrrfdNq2FGHYX4gx5YDT1DvgmkccSee1U",
]
//deploys the contract and gets an instance of it to work with
beforeEach(async () => {
accounts = await ethers.getSigners()
deployer = accounts[0]
user = accounts[1]
await deployments.fixture(["mintnft"])
mintNFT = await ethers.getContract("MintNFT")
})
// constructor
describe("Deployment", function () {
it("Should have the correct name and symbol", async function () {
expect(await mintNFT.name()).to.equal(_name)
expect(await mintNFT.symbol()).to.equal(_symbol)
})
it("should set the right owner", async function () {
expect(await mintNFT.owner()).to.equal(deployer.address)
})
})
// bulkMint()
describe("It mints 10NFTs", function () {
it("Should be reverted as caller is not owner", async function () {
await expect(mintNFT.connect(user).bulkMint(tokensUris)).to.be.revertedWith(
"Ownable: caller is not the owner"
)
})
it("Should emit the NFtMinted event after each token minted", async function () {
for (i = 0; i < tokensUris.length; i++) {
let index = i
await expect(mintNFT.bulkMint(tokensUris))
.to.emit(mintNFT, "NFTMinted")
.withArgs(tokensUris[i], index)
}
})
describe("View token ID to check that counter is at 10", function () {
let tokencounter = 10
it("Should return a token counter of 10 if all NFTs have been successfully minted", async function () {
await mintNFT.bulkMint(tokensUris)
expect(await mintNFT.getTokenId()).to.equal(tokencounter)
})
})
//after calling buklMint(), grab the tokenURIs and test them individually = getURI(0)="ipfs://..."
describe("Each token URI is properly initialized", function () {
it("Should set the token URIs to their correct ipfs addresses", async function () {
await mintNFT.bulkMint(tokensUris)
//assumes that the bulkMint() is correctly working. If it is, it will initialize _allTokenURIs and viewUris() will return them
for (i = 0; i < tokensUris.length; i++) {
expect(await mintNFT.viewURIs(i)).to.equal(tokensUris[i])
console.log(await mintNFT.viewURIs(i), "is equal to", tokensUris[i])
}
})
})
})
})
When running tests, here are the results :
anne#AnneSager:~/HAAAAAAAA/newTry$ yarn hardhat test
yarn run v1.22.15
warning package.json: No license field
warning ../../package.json: No license field
$ /home/anne/HAAAAAAAA/newTry/node_modules/.bin/hardhat test
Compiled 1 Solidity file successfully
Basic NFT minting tests
Deployment
✔ Should have the correct name and symbol (40ms)
✔ should set the right owner
It mints 10NFTs
✔ Should be reverted as caller is not owner (74ms)
1) Should emit the NFtMinted event after each token minted
View token ID to check that counter is at 10
✔ Should return a token counter of 10 if all NFTs have been successfully minted (174ms)
Each token URI is properly initialized
ipfs://QmaGmVJianGd3wzdfRNFZXWA9UeMdLFMBX5cZZSZjNeckP is equal to ipfs://QmaGmVJianGd3wzdfRNFZXWA9UeMdLFMBX5cZZSZjNeckP
ipfs://QmaGV6P2knFkPdStvPsNXjJjehEysfnK7e4tShJAvpuPrx is equal to ipfs://QmaGV6P2knFkPdStvPsNXjJjehEysfnK7e4tShJAvpuPrx
ipfs://QmcdbzSUFhRF98ppNHf83yhPJ2jHjP5Lpuov9Wzi4aYZF4 is equal to ipfs://QmcdbzSUFhRF98ppNHf83yhPJ2jHjP5Lpuov9Wzi4aYZF4
ipfs://QmP8W1KEC2td2VPn3tbEYjFBZ2yV6jZh5Fbe2rGjzqCMwS is equal to ipfs://QmP8W1KEC2td2VPn3tbEYjFBZ2yV6jZh5Fbe2rGjzqCMwS
ipfs://QmdL2QjcLPjd1RLwHK1GNuNQSt5b4ZXupuaGYtUi3Lqqz5 is equal to ipfs://QmdL2QjcLPjd1RLwHK1GNuNQSt5b4ZXupuaGYtUi3Lqqz5
ipfs://QmaJqsMKbFLLTZszY2rprPRncDReLTnhHVdz2U7aScxFNS is equal to ipfs://QmaJqsMKbFLLTZszY2rprPRncDReLTnhHVdz2U7aScxFNS
ipfs://QmYeioLfMcTUNSABndwqJz7sjaeA7quF1fMGq2tziSE2T3 is equal to ipfs://QmYeioLfMcTUNSABndwqJz7sjaeA7quF1fMGq2tziSE2T3
ipfs://QmW7nRHE7J5L36n9NvxspwNfSbEPRcFvDF4kUkscZHehyZ is equal to ipfs://QmW7nRHE7J5L36n9NvxspwNfSbEPRcFvDF4kUkscZHehyZ
ipfs://QmUcCwpskbvQydNa3rcSpCftsPAmBgovn6WnZYTeZw4NpU is equal to ipfs://QmUcCwpskbvQydNa3rcSpCftsPAmBgovn6WnZYTeZw4NpU
ipfs://QmdyTVfRymf2kFrrfdNq2FGHYX4gx5YDT1DvgmkccSee1U is equal to ipfs://QmdyTVfRymf2kFrrfdNq2FGHYX4gx5YDT1DvgmkccSee1U
✔ Should set the token URIs to their correct ipfs addresses (383ms)
5 passing (2s)
1 failing
1) Basic NFT minting tests
It mints 10NFTs
Should emit the NFtMinted event after each token minted:
AssertionError: Specified args not emitted in any of 10 emitted "NFTMinted" events
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
I've run the same code with only changing the arguments in the NFTMinted event, passing it only the uri variable, and the 6 tests passed successfully.
So my problem comes from my tokenId... I've tried not using Counters and initializing my own uint256 tokenId, but the error was the same, AssertionError: Specified args not emitted in any of 10 emitted "NFTMinted" events.
Any help would be greatly appreciated :)
Other info:
package.json :
{
"devDependencies": {
"#nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers",
"#nomiclabs/hardhat-etherscan": "^3.1.0",
"#nomiclabs/hardhat-waffle": "^2.0.3",
"#openzeppelin/contracts": "^4.7.2",
"#pinata/sdk": "^1.1.26",
"chai": "^4.3.6",
"dotenv": "^16.0.1",
"ethereum-waffle": "^3.4.4",
"ethers": "^5.6.9",
"hardhat": "^2.10.1",
"hardhat-contract-sizer": "^2.6.1",
"hardhat-deploy": "^0.11.12",
"hardhat-gas-reporter": "^1.0.8",
"path": "^0.12.7",
"prettier": "^2.7.1",
"prettier-plugin-solidity": "^1.0.0-dev.23",
"solhint": "^3.3.7",
"solidity-coverage": "^0.7.21"
}
}
running on Linux Ubuntu 20.4
using VSCode
UPDATE
Derawi's comment made me run through my code again to try to figure out how to not call the bulkMint() function 10 times.
I have not managed to fix it yet, but the changes I made brought a new error that allows me to push my thought process forward.
Changes
modified my bulkMint()
function bulkMint(string[] memory uris)
public
onlyOwner
{
_allTokenURIs = uris;
address to = msg.sender;
for (uint256 i = 0; i < _allTokenURIs.length; i++) {
string memory uri = _allTokenURIs[i];
safeMint(to, uri);
}
}
mint-unit.js test file :
describe("It mints 10NFTs", function () {
it("Should be reverted as caller is not owner", async function () {
await expect(mintNFT.connect(user).bulkMint(tokensUris)).to.be.revertedWith(
"Ownable: caller is not the owner"
)
})
it("Should emit the NFtMinted event after each token minted", async function () {
await mintNFT.bulkMint(tokensUris)
for (i = 0; i < tokensUris.length; i++) {
let index = i
let uri = tokensUris[index]
await expect(mintNFT.safeMint(deployer.address, uri))
.to.emit(mintNFT, "NFTMinted")
.withArgs(index, uri)
}
})
Now the error message is :
1) Basic NFT minting tests
It mints 10NFTs
Should emit the NFtMinted event after each token minted:
AssertionError: Expected "11" to be equal 0
at assertArgsArraysEqual (node_modules/#ethereum-waffle/chai/dist/cjs/matchers/emit.js:58:54)
at tryAssertArgsArraysEqual (node_modules/#ethereum-waffle/chai/dist/cjs/matchers/emit.js:65:20)
at /home/anne/HAAAAAAAA/newTry/node_modules/#ethereum-waffle/chai/dist/cjs/matchers/emit.js:77:13
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at runNextTicks (node:internal/process/task_queues:65:3)
at listOnTimeout (node:internal/timers:528:9)
at processTimers (node:internal/timers:502:7)
at Context.<anonymous> (test/mint-unit.js:61:13)
Any help is still appreciated, I can tell I've messed somewhere, but still can't figure out if it's on the contract, on the test, or on both :/
So I have major problem with importing from one class to another and what I have done is in my "main" class which I call
detailsPage.js
import { DetailsPage } from '../tests/detailsPageObj';
const utils = require("../utils/utils");
const assert = require('../node_modules/chai').assert;
const userData = require('../globalContent.json');
describe('Details page', function () {
const detailsPage = new DetailsPage();
// The details page is accessible by the specified URL
it(`Is defined by the URL: ${userData.url}`, async function () {
await detailsPage.navigate();
});
// Details page has a form and it can be filled out with user data
it('Has a form that can receive user data', async function () {
await detailsPage.fillFormWithUserData(); // If you want, make the user data passable to the method
await utils.click(detailsPage.form.buttons.nextStep);
});
if (detailsPage.hasStockConflict) {
// Details page allows the user to fix conflicts in stocks
it('Enables resolution of stock conflicts', async function () {
// Wait for stock to fully load
await browser.sleep(2000);
await detailsPage.clickAllRemoveButtons();
await detailsPage.clickAllDecreaseButtons();
});
}
// Details page allows the user to proceed to the next stage when all conflicts (if any) has been resolved
it('Allows the user to proceed to the next stage of purchasing', async function () {
const nextStepButton = detailsPage.form.buttons.nextStep;
await utils.elementToBeClickable(nextStepButton);
await utils.click(nextStepButton);
});
});
and what I am trying tod o is to get DetailsPage from another script which is called:
detailsPageObj
import { element, by } from 'protractor';
const utils = require("../utils/utils");
const userData = require('../globalContent.json');
export class DetailsPage {
get pageUtils() {
return {
qtyRegex: /^Sorry.*?(\d+)/
}
}
private get fields() {
return {
email: element(by.id('email')),
firstName: element(by.id('firstName')),
lastName: element(by.id('lastName')),
postalCode: element(by.id('postalCode')),
addressOne: element(by.id('addressOne')),
addressTwo: element(by.id('addressTwo')),
phone: element(by.id('phone')),
businessCustomerCB: element(by.id('isBusinessCustomer')),
company: element(by.id('company')),
GST: element(by.id('gst')),
}
}
private get groups() {
return {
address: element(by.css('div#addressGroup.input-container.showHiddenGroup'));
company: element(by.id('companyGroup')),
}
}
private get modals() {
return {
contactModalLink: element(by.id('contactModalLink')),
cross: element(by.className('modal-cross')),
}
}
private get formButtons() {
return {
nextStep: element(by.id('submitIdentityFormButton')),
mobile: this.mobileFormButtons
}
}
private get mobileFormButtons() {
return {
continue: element(by.id('stock-conflict-continue-button')),
removeOutOfStockItems: element(by.css('button[id="removeOutOfStockItems"]')), // I just assumed that this is a part of the form
}
}
private get productFrameMobileButtons() {
return {
stockControll: element.all(by.className('stock-controller mobile')),
remove: element.all(by.className('btn btn-remove btn-outlined mobile')),
}
}
private get productFrameDesktopButtons() {
return {
stockControll: element.all(by.className('stock-controller desktop')),
remove: element.all(by.className('btn btn-remove btn-outlined desktop')),
}
}
get form() {
return {
fields: this.fields,
groups: this.groups,
buttons: this.formButtons,
modals: this.modals
}
}
get productFrame() {
return {
buttons: {
decrease: element.all(by.className("btn left")).first(),
mobile: this.productFrameMobileButtons,
desktop: this.productFrameDesktopButtons
}
}
}
get errors() {
return {
stockConflict: element(by.className('generic-error-heading')),
}
}
}
and what I am trying to do is in detailsPage.js im trying to import detailsPageObj.js but whenever I am trying to do it I do get SyntaxError: Cannot use import statement outside a module.
What am I doing wrong
I don't know what is your environment like, but I experienced a similar problem where my environment used a full build step for creating the target JS code from my sources (e.g. from TypeScript or from ES6+) to a bundled/plain JS.
But then my test environment did not have any build step. So when I executed the tests, it only understood plain JS, which by default in a node.js environment does not recognize import but only require.
You can use import in your node.js code without a build step, but you need to follow some steps, e.g. rename your file from *.js to *.mjs. More details here.
For some reason, i get a "post.save is not a function" on using the .save() function on astronomy v2. i tried to call the .save() on inserting a new doc in the db using a meteor methods call from the client side.
Here's some code :
import { Class } from 'meteor/jagi:astronomy';
import { Mongo } from 'meteor/mongo';
const Posts = new Mongo.Collection("Posts");
const Post = Class.create({
name: 'Post',
Collection : Posts,
secured: true,
fields: {
title: String,
published: Boolean,
/* ... */
},
methods: {
rename(title) {
// Check if a given user can rename this post.
if (this.ownerId !== Meteor.userId()) {
throw new Meteor.Error(403, 'You are not an owner');
}
this.title = this;
this.save();
},
publish() {
// Check if a given user can publish this post.
if (this.ownerId !== Meteor.userId()) {
throw new Meteor.Error(403, 'You are not an owner');
}
if (this.published) {
throw new Meteor.Error(403, 'Post is already published');
}
this.published = true;
this.save();
}
}
});
Meteor.methods({
"newPost"(){
const post = new Post();
post.title = "test";
post.save();
},
"renamePost"(postId, title) {
const post = Post.findOne(postId);
post.rename(title);
},
"publishPost"(postId) {
const post = Post.findOne(postId);
post.publish();
}
});
As you can see im using the samples on the astronomy documentation with an additional methods called newPost.
calling on those functions all resulted in an Exception
TypeError: post.save is not a function
Have tried the following tries on resolving the error with no success
Removing and re adding astronomy
Rebuild meteor project
Updating to latest 2.1.2 version
Thx for the answers !
It looks like method dont know about Astronomy.Class.
You export your class?
I am sending userid from javascript while i am making request to signalr as follows:
var userId = "1";
var connection = $.hubConnection("/signalr", { useDefaultPath: false });
var notificationsHubProxy = connection.createHubProxy('NotificationsHub');
connection.qs = "userId=" + userId;
notificationsHubProxy.on('notify', function (notifications) {
notifyAll(notifications);
});
connection.start()
.done(function() {
notificationsHubProxy.invoke('getNotifications', "1,2,3");
})
.fail(function(reason) {
alert('signalr error');
});
Here is the class for implementing IUserIdProvider that retrieves querystring and returns as userId, i debugged and this class and GetUserId method was not invoked by the framework.
public class RealTimeNotificationsUserIdProvider : IUserIdProvider
{
public string GetUserId(IRequest request)
{
return request.QueryString["userId"];
}
}
Here is my startup class for hooking up IUserId provider with signalR configuration:
var userIdProvider = new RealTimeNotificationsUserIdProvider();
GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider), () => userIdProvider);
app.Map("/signalr", map =>
{
var hubConfiguration = new HubConfiguration
{
EnableDetailedErrors = true,
Resolver = dependencyResolver,
EnableJavaScriptProxies = false
};
map.RunSignalR(hubConfiguration);
});
Now, when i try to send notification to a particular User by accessing Clients.User(userId) its not working:
var userId = "1";
Clients.User(userId).notify("test");
what am i missing? Please help.
What you have looks like it should work. The only thing that looks suspicious is that you are registering your IUserIdProvider with GlobalHost.DependencyResolver, but then you have Resolver = dependencyResolver in your HubConfiguration.
There is no other reference to dependencyResolver anywhere else in your question. If you were to leave out Resolver = dependencyResolver, SignalR would use GlobalHost.DependencyResolver by default.
hier is what I did to solve this problem, form me request.QueryString["userId"] did not return user id that is why it did not work, I change your code like below and it does work I tested t on my project:
using using System.Web;
public class RealTimeNotificationsUserIdProvider : IUserIdProvider
{
public string GetUserId(IRequest request)
{
return HttpContext.Current.User.Identity.GetUserId()
}
}
remove var userIdProvider = new RealTimeNotificationsUserIdProvider() and write it like below:
ConfigureAuth(app);
GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider), () => new RealTimeNotificationsUserIdProvider());
app.Map("/signalr", map =>
{
var hubConfiguration = new HubConfiguration
{
EnableDetailedErrors = true,
EnableJavaScriptProxies = false
};
map.RunSignalR(hubConfiguration);
});